简体   繁体   English

从 .Net Core 运行 Powershell - 无法加载文件或程序集 Microsoft.Management.Infrastructure

[英]Running Powershell from .Net Core - Could not load file or assembly Microsoft.Management.Infrastructure

I have been trying to run a powershell script from a.Net Core Web app (not discussing best practices here;) ) with the following code:我一直在尝试使用以下代码从 .Net Core Web 应用程序运行 powershell 脚本(此处不讨论最佳实践;)):

    string command = @"& """c:\\my Folder\\myScript.ps1""";

    using (var ps = PowerShell.Create())
    {
        var results = ps.AddScript(command).Invoke();
    }

It works well on my dev machine, but in production it fails when trying to execute this function:它在我的开发机器上运行良好,但在生产环境中尝试执行此 function 时失败:

ps.AddScript(command).Invoke()

I get the following exception:我得到以下异常:

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. System.IO.FileNotFoundException:无法加载文件或程序集“Microsoft.Management.Infrastructure,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”。 The system cannot find the file specified.该系统找不到指定的文件。 File name: 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes) 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, Boolean isModuleLoad, Dictionary 2& cmdlets, Dictionary 2& aliases, Dictionary 2& providers, String helpFile, Type& randomCmdletToCheckLinkDemand, Type& randomProviderToCheckLinkDemand) at System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzePSSnapInAssembly(Assembly assembly, String name, PSSnapInInfo psSnapInInfo, PSModuleInfo moduleInfo, Boolean isModuleLoad, Dictionary 2& cmdlets, Dictionary 2& aliases, Dictionary文件名:'Microsoft.Management.Infrastructure,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35' at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes) at System.Management.Automation.Automation.Runspaces.PSSnapInHelpers.GetAssemblyTypes(程序集程序集,字符串名称)在 System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzeModuleAssemblyWithReflection(程序集程序集,字符串名称,PSSnapInInfo psSnapInInfo,PSModuleInfo 模块信息,Boolean,Dictionary2 2& cmdlets, Dictionary Loadlets 2& cmdlets, Dictionary 2 和别名,字典2& providers, String helpFile, Type& randomCmdletToCheckLinkDemand, Type& randomProviderToCheckLinkDemand) at System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzePSSnapInAssembly(Assembly assembly, String name, PSSnapInInfo psSnapInInfo, PSModuleInfo moduleInfo, Boolean isModuleLoad, Dictionary 2& aliases, 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() at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync) at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection 1 input, PSDataCollection 1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection 1 input, PSDataCollection 1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, System.Management.Automation.Runspaces.InitialSessionState.ImportPSSnapIn(PSSnapInInfo 2& aliases, Dictionary , PSSnapInException& warning) 在 System.Management.Automation.Runspaces.InitialSessionState.CreateDefault() 在 System.Management.Automation.Runspaces.RunspaceFactory System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace() 在 System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(运行空间 rsToUse,Boolean isSync)在 System.Management.Automation.88271438ke[ TInput,TOutput](PSDataCollection 1 input, PSDataCollection 1 output,PSInvocationSettings 设置)在 System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection 1 input, PSDataCollection 1 output,PSInvocationManages 设置)。 PowerShell.CoreInvoke[TOutput](IEnumerable 输入,PSDataCollection`1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings) PSInvocationSettings 设置)在 System.Management.Automation.PowerShell.Invoke(IEnumerable 输入,PSInvocationSettings 设置)

I don't know which framework/package I am suppose to install to make it run.我不知道我应该安装哪个框架/包来让它运行。 Target Framework is.Net Core 2.1 which is installed, hence the application running fine except line mentionned above.目标框架是已安装的 .Net Core 2.1,因此应用程序运行良好,除了上面提到的行。

The deps.json file contains this: deps.json 文件包含以下内容:

    "Microsoft.Management.Infrastructure/1.0.0": {
        "dependencies": {
          "NETStandard.Library": "2.0.3",
          "System.Runtime.CompilerServices.VisualC": "4.3.0",
          "System.Runtime.Serialization.Xml": "4.3.0",
          "System.Security.SecureString": "4.3.0",
          "System.Threading.ThreadPool": "4.3.0"
        },
        "compile": {
          "ref/netstandard1.6/Microsoft.Management.Infrastructure.Native.dll": {},
          "ref/netstandard1.6/Microsoft.Management.Infrastructure.dll": {}
        }
      }

Nuget Packages installed: Nuget 安装的包:

Microsoft.AspNetCore.App (2.1.1)
Microsoft.PowerShell.Commands.Diagnostics (6.0.5)
Microsoft.PowerShell.SDK (6.0.5)
Microsoft.PowerShell.WSMan.Management (6.0.5)

Edit I also added Microsoft.Management.Infrastructure (1.0.0) but it didn't fix the issue编辑我还添加了 Microsoft.Management.Infrastructure (1.0.0) 但它没有解决问题

Edit2 Dev is Windows 10 Pro and Prod is Windows Server 2016 Standard Edit2 Dev 是 Windows 10 Pro,Prod 是 Windows Server 2016 Standard

Edit3 The script runs fine on prod when launched through PowerShell directly. Edit3当直接通过 PowerShell 启动时,脚本在产品上运行良好。 The error shown is when the Web app tries to run PowerShell.显示的错误是当 Web 应用程序尝试运行 PowerShell 时。

Edit4 App pool account has admin rights and is the same account that I used to run the script manually (not good practice but for now I'm just trying to make this run). Edit4应用程序池帐户具有管理员权限,并且与我用来手动运行脚本的帐户相同(不是很好的做法,但现在我只是想运行这个)。

Edit5 I tried to put the dll in the folder of the app on the server and restart the site + recycle the application pool. Edit5我尝试将 dll 放在服务器上应用程序的文件夹中,然后重新启动站点 + 回收应用程序池。 I tried with every version I could find on the dev machine and nothing worked:/我尝试了在开发机器上可以找到的每个版本,但没有任何效果:/

Edit6 Updated nuget packages from 6.0.5 to latest 6.2.1, same issue Edit6 将nuget 包从 6.0.5 更新到最新的 6.2.1,同样的问题

I had same issue, Microsoft.Management.Infrastructure.dll (and associated files) did not get published. 我有同样的问题, Microsoft.Management.Infrastructure.dll (和相关文件)没有发布。 Solved by specifying a non-portable RID in publish profile ( *.pubxml , not the *.csproj ): 通过在发布配置文件中指定非可移植RID*.pubxml而不是 *.csproj )来解决:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

Problem is probably caused by the fact, that under C:\\Users\\UserName\\.nuget\\packages\\microsoft.management.infrastructure\\1.0.0\\runtimes there are only folders with non-portable RIDs; 问题可能是由于在C:\\Users\\UserName\\.nuget\\packages\\microsoft.management.infrastructure\\1.0.0\\runtimes下的事实导致只有非便携式RID的文件夹; there is no win-x86 and win-x64 . 没有win-x86win-x64

Check application identity pool for Web app in pool. 检查池中Web应用程序的应用程序标识池。 It may be rights issue Use identity impersonation or run on admin account. 它可能是权利问题使用身份模拟或在管理员帐户上运行。 when you run from console you run with your identity when you run with app its app identity pool 当您使用应用程序的应用程序标识池运行时,从控制台运行时,您将使用您的身份运行

You can load any DLL from Powershell, so one solution that should definitely work is loading the Microsoft.Management.Infrastructure DLL as part of the script. 您可以从Powershell加载任何DLL,因此一个绝对有效的解决方案是将Microsoft.Management.Infrastructure DLL作为脚本的一部分加载。 But before doing that, let's verify the difference between what's loaded in dev and prod powershell sessions. 但在此之前,让我们验证开发和prod powershell会话中加载的内容之间的区别。

You can get the list of currently loaded assemblies in PowerShell by running [Threading.Thread]::GetDomain().GetAssemblies() . 您可以通过运行[Threading.Thread]::GetDomain().GetAssemblies()获取PowerShell中当前加载的程序集列表。 Add this line at the start and end of your script (at the end because PowerShell will auto-load referenced assemblies if it can, when they are first used in the script). 在脚本的开头和结尾添加此行(最后,因为PowerShell将自动加载引用的程序集,如果可以的话,首次在脚本中使用时)。 Now run the script on dev and prod and compare the results. 现在在dev和prod上运行脚本并比较结果。 Chances are, Microsoft.Management.Infrastructure will be missing on prod. 很可能, Microsoft.Management.Infrastructure将在prod上失踪。

The assemblies list output shows the location of the assemblies. 程序集列表输出显示程序集的位置。 From the dev list, grab the Microsoft.Management.Infrastructure DLL file. 从开发人员列表中,获取Microsoft.Management.Infrastructure DLL文件。 You now have two options: 您现在有两个选择:

  1. Put the file in the prod machine's GAC. 将文件放入prod机器的GAC中。 PowerShell should now load the DLL automatically as required. PowerShell现在应该根据需要自动加载DLL。
  2. Make loading this DLL file part of your PowerShell script. 将此DLL文件加载到PowerShell脚本中。 Add [Reflection.Assembly]::LoadFile($fullPathToDLL) at the start of your script (or anywhere before you use Microsoft.Management.Infrastructure ). 在脚本开头(或使用Microsoft.Management.Infrastructure之前的任何位置[Reflection.Assembly]::LoadFile($fullPathToDLL)添加[Reflection.Assembly]::LoadFile($fullPathToDLL) )。

将此添加到您的 csproj 中。

<PackageReference Include="NETStandard.Library" Version="1.6.1" />

publish using... dotnet publish -o.\publish -r win10-x64发布使用... dotnet publish -o.\publish -r win10-x64

https://github.com/PowerShell/PowerShell/issues/7886 https://github.com/PowerShell/PowerShell/issues/7886

My converted project had a top-level package System.Management.Infrastructure which was pulling in a transitive dependency for the missing Microsoft.Management.Infrastructure 1.0.我转换后的项目有一个顶级 package System.Management.Infrastructure,它正在为缺少的 Microsoft.Management.Infrastructure 1.0 引入传递依赖。 . . So, I eliminated that and now the correct transitive package Microsoft.Management.Infrastructure 2.0.所以,我消除了它,现在正确的传递 package Microsoft.Management.Infrastructure 2.0。 package is being pulled in by the PowerShell.* 2.0 packages. package 被 PowerShell.* 2.0 包拉入。 Note that you can see this using a nifty new feature of VS2022 (version 17.3.5) where you can hover over the transitive packages to see which top-level packages are pulling them in.请注意,您可以使用 VS2022(版本 17.3.5)的一个漂亮的新功能看到这一点,您可以在传递包上 hover 查看哪些顶级包将它们拉入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM