在.NET 8 RC2中运行PowerShell 7时无法加载Microsoft.Management.Infrastructure 1.0
问题场景与报错信息
环境配置
- 运行环境:.NET 8.0.100-rc.2.23502.2 x64,VS2022 17.8预览版4
- 本地已安装:PowerShell Core 7、Windows PowerShell 5.1
- NuGet依赖:
Microsoft.PowerShell.SDK 7.3.8,其依赖链:Microsoft.Management.Infrastructure.CimCmdlets 7.3.8System.Management.Automation 7.3.8Microsoft.Management.Infrastructure 2.0
触发操作
执行以下代码时出现错误:
var rs = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(); // 或 var ps = System.Management.Automation.PowerShell.Create();
错误信息
Exception thrown: 'System.IO.FileNotFoundException' in System.Private.CoreLib.dll An exception of type 'System.IO.FileNotFoundException' occurred in System.Private.CoreLib.dll but was not handled in user code Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
堆栈跟踪
at System.Reflection.RuntimeAssembly.GetExportedTypes() at System.Management.Automation.Runspaces.PSSnapInHelpers.GetAssemblyTypes(Assembly assembly, String name) at System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzeModuleAssemblyWithReflection(Assembly assembly, String name, PSSnapInInfo psSnapInInfo, PSModuleInfo moduleInfo, String helpFile, Dictionary`2& cmdlets, Dictionary`2& aliases, Dictionary`2& providers) at System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzePSSnapInAssembly(Assembly assembly, String name, PSSnapInInfo psSnapInInfo, PSModuleInfo moduleInfo, Dictionary`2& cmdlets, Dictionary`2& aliases, Dictionary`2& providers, String& helpFile) at System.Management.Automation.Runspaces.InitialSessionState.ImportPSSnapIn(PSSnapInInfo psSnapInInfo, PSSnapInException& warning) at System.Management.Automation.Runspaces.InitialSessionState.CreateDefault() at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(PSHost host) at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
编译警告
1>C:\Program Files\dotnet\sdk\8.0.100-rc.2.23502.2\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): warning NETSDK1206: Found version-specific or distribution-specific runtime identifier(s): win10-x64, win10-x86, win7-x64, win7-x86, win81-x64, win81-x86, win8-x64, win8-x86. Affected libraries: Microsoft.Management.Infrastructure.Runtime.Win. In .NET 8.0 and higher, assets for version-specific and distribution-specific runtime identifiers will not be found by default.
疑问
- 为何NuGet依赖2.0版本的DLL,运行时却尝试加载1.0版本?
- 是否无法在.NET 8中使用PowerShell SDK 7.x NuGet包?
- 降级到.NET 7是否可行?
- 若所有方法失效,是否只能通过
Process类调用powershell.exe?
解决方案
1. 添加程序集绑定重定向
PowerShell SDK的部分组件可能仍保留对Microsoft.Management.Infrastructure 1.0版本的引用,需通过绑定重定向将旧版本请求指向已安装的2.0版本。
方法一:修改项目文件
在.csproj中添加以下配置:
<PropertyGroup> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> </PropertyGroup>
方法二:手动配置app.config
若自动生成无效,可在项目的app.config(或web.config)中添加手动重定向规则:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Microsoft.Management.Infrastructure" publicKeyToken="31bf3856ad364e35" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
2. 处理NETSDK1206警告
.NET 8默认不再支持版本特定的Runtime Identifier(如win10-x64),需调整RID配置:
方法一:使用通用RID
在项目文件中指定通用的运行时标识:
<PropertyGroup> <RuntimeIdentifier>win-x64</RuntimeIdentifier> </PropertyGroup>
方法二:启用版本特定RID兼容
若必须保留旧RID,可启用兼容开关:
<PropertyGroup> <EnableVersionSpecificRidAssets>true</EnableVersionSpecificRidAssets> </PropertyGroup>
3. 降级到.NET 7
完全可行。PowerShell SDK 7.3.x原生适配.NET 7,降级后可直接避免版本兼容性问题,这是最快捷的临时解决方案,直到官方推出适配.NET 8的PowerShell SDK正式版本。
4. 替代方案:通过Process调用PowerShell
若上述方法均无效,可直接通过System.Diagnostics.Process调用独立的PowerShell进程,这种方式不依赖SDK,兼容性最强,但需自行处理输入输出的序列化与错误捕获。示例代码:
using System.Diagnostics; var processStartInfo = new ProcessStartInfo { FileName = "pwsh.exe", // PowerShell Core,若用Windows PowerShell则改为powershell.exe Arguments = "-Command \"Get-ChildItem C:\\\"", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, StandardOutputEncoding = System.Text.Encoding.UTF8, StandardErrorEncoding = System.Text.Encoding.UTF8 }; using var process = Process.Start(processStartInfo); string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); Console.WriteLine("输出结果:"); Console.WriteLine(output); if (!string.IsNullOrEmpty(error)) { Console.WriteLine("\n错误信息:"); Console.WriteLine(error); }
内容的提问来源于stack exchange,提问作者andy250
相关产品推荐
相关产品推荐

