You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 5插件架构中调用PowerShell的Get-Disk cmdlet失败问题

问题根因

你遇到的报错是.NET插件的AssemblyLoadContext(ALC)隔离机制和PowerShell SDK的依赖加载逻辑冲突导致的:

  1. 按照官方插件教程实现的加载逻辑会给每个插件分配独立的ALC,插件引用的所有NuGet包默认都会在这个独立ALC中加载,和主程序的默认ALC完全隔离
  2. Storage是Windows内置的CIM类型PowerShell模块,加载时会依赖全局上下文中的System.Management.Automation、Microsoft.PowerShell.*等核心程序集的类型定义
  3. 插件独立ALC中加载的PowerShell核心程序集和系统模块预期的默认ALC中的程序集属于不同实例,对应类型无法被识别,就会触发getter方法参数不匹配的报错,进而导致Storage模块加载失败
  4. 你在插件外部调用能正常运行,是因为直接调用时PowerShell SDK是加载在主程序默认ALC中的,类型匹配不存在隔离问题。

解决方案

  • 方案1:调整插件ALC的加载逻辑,共享PowerShell相关程序集
    重载你实现的插件ALC类的Load方法,遇到PowerShell相关程序集时直接从主程序的默认ALC加载,不要在插件独立ALC中重复加载:

    protected override Assembly Load(AssemblyName assemblyName)
    {
        // 匹配所有PowerShell核心程序集,走默认上下文加载
        if (assemblyName.Name.StartsWith("Microsoft.PowerShell") || 
            assemblyName.Name.StartsWith("System.Management.Automation"))
        {
            return AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);
        }
        // 其余插件专属程序集保留原有加载逻辑即可
        // ...
    }
    

    注意主项目需要和插件引用相同版本的Microsoft.PowerShell.SDK NuGet包,避免版本不匹配的加载错误。

  • 方案2:指定PowerShell使用全局运行空间
    创建PowerShell实例时指定使用当前进程的默认运行空间,绕开插件独立上下文的加载限制,适合没有多线程并发调用PowerShell的场景:

    // 修改实例创建参数即可
    using (PowerShell ps = PowerShell.Create(RunspaceMode.CurrentRunspace))
    {
        ps.AddScript("Import-Module Storage; Get-Disk");
        ps.Invoke();    
        Console.WriteLine(string.Join(", ", ps.Streams.Error));
    }
    
  • 方案3:绕过PowerShell模块直接调用CIM接口
    如果仅需要获取磁盘等系统硬件信息,可以直接引用Microsoft.Management.Infrastructure NuGet包调用CIM接口,完全避免PowerShell模块加载的相关问题,性能也更优。


内容的提问来源于stack exchange,提问作者SuperJMN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:57:03