Running PowerShell 7 from .net 8 (rc2) - cannot load Microsoft.Management.Infrastructure 1.0

739 views Asked by At

I am trying to run some powershell from C# (.net 8.0.100-rc.2.23502.2 x64, VS2022 17.8 preview 4). Locally I have installed powershell core 7 and Windows powershell 5.1. My .net project has installed Microsoft.PowerShell.SDK 7.3.8 from nuget with following dependency chain:

  • Microsoft.Management.Infrastructure.CimCmdlets 7.3.8
  • System.Management.Automation 7.3.8
  • Microsoft.Management.Infrastructure 2.0

When executing this line: var rs = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(); or this line: var ps = System.Management.Automation.PowerShell.Create();

I get this error:

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.

EDIT: Stack trace

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()

Not sure why the nuget package depends on 2.0 version of the DLL but still wants to load 1.0. I also get this warning in VS wn building the project:

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. See https://aka.ms/dotnet/rid-usage for details.

Does it mean it is not possible to use PowerShell SDK 7.x nuget package with .net8 because of the above warning and version-sepcific DLLs not being loaded by default? I tried also loading it manually, with no success (System.Reflection.Assembly.LoadFrom(pathToDll)).

Would it work if I downgraded to .net7 for instance? If all fails - is the only workaround to run powershell.exe using Process class?

EDIT 2: I can reproduce this on 2 development machines (win10 and win11)

1

There are 1 answers

0
andy250 On BEST ANSWER

Thanks to @jdweng comment I found this article: https://learn.microsoft.com/en-us/dotnet/core/tools/sdk-errors/netsdk1206

It contains a workaround. Long term fix would be for PowerShell authors to use only portable RIDs in their package dependencies.

To use the workaround: as explained in above article add this piece of XML to the .csproj file of the executing project:

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Runtime.Loader.UseRidGraph" Value="true" />
</ItemGroup>

I created this ticket at PowerShell's GitHub: https://github.com/PowerShell/PowerShell/issues/20559