简体   繁体   English

System.Management.Automation.dll 版本混淆

[英]System.Management.Automation.dll versioning confusion

I have a "core" assembly that contains a series of PowerShell Cmdlets written in C#.我有一个“核心”程序集,其中包含一系列用 C# 编写的 PowerShell Cmdlet。 I also have a WPF "gui" application that uses this "core" assembly.我还有一个使用这个“核心”程序集的 WPF“gui”应用程序。 In order use and compile the "core", I obviously need PowerShell's types and therefore I added a reference to System.Management.Automation.dll to my project.为了使用和编译“核心”,我显然需要 PowerShell 的类型,因此我在我的项目中添加了对System.Management.Automation.dll的引用。 I did this by simply adding a reference to that DLL from my local machines GAC.我通过简单地从我的本地机器 GAC 添加对该 DLL 的引用来做到这一点。 Everything compiles and runs smoothly on my machine.一切都在我的机器上编译并顺利运行。

When I deploy & run my "gui" on a different machine, I get strange errors.当我在另一台机器上部署和运行我的“gui”时,出现奇怪的错误。 For example:例如:

System.MissingMethodException: Method not found: 'System.Management.Automation.PSDataCollection`1<System.Management.Automation.InformationRecord> System.Management.Automation.PSDataStreams.get_Information()'

I have narrowed the cause down to this: My "gui" implements a custom PowerShell host and loads the "core" and executes it's cmdlets.我已将原因缩小到这一点:我的“gui”实现了一个自定义 PowerShell 主机并加载“核心”并执行它的 cmdlet。 It is done like so:它是这样完成的:

  Host = new MyCustomHost();
  var rs = RunspaceFactory.CreateRunspace(Host);
  PsInstance = PowerShell.Create();

  PsInstance.Runspace = rs;
  rs.Open();

  PsInstance.Streams.Information.DataAdded += delegate (object s, DataAddedEventArgs e)
  {
    nvtLogger.WriteInformation(PsInstance.Streams.Information[e.Index].MessageData.ToString());
  };

Apparently the property PsInstance.Streams.Information is not found during runtime.显然,在运行时找不到属性PsInstance.Streams.Information

I found that the System.Management.Automation.dll that I added as a reference to the project is not necessarily the one getting loaded.我发现作为项目引用添加的System.Management.Automation.dll不一定是加载的那个。 The framework first looks into the GAC, and if it finds a copy there, it uses that one instead of mine.该框架首先查看 GAC,如果在那里找到副本,它会使用该副本而不是我的副本。

I understand that the cause for the issue is, that the deployment machine has an older version of PowerShell installed, which does not implement the property I am using - and throws the exception above.我知道问题的原因是部署机器安装了旧版本的 PowerShell,它没有实现我正在使用的属性 - 并抛出上述异常。

What I do not understand, however, is: how can the framework load this assembly from the GAC, when it is not compatible with the one I have built against?然而,我不明白的是:当它与我构建的程序集不兼容时,框架如何从 GAC 加载这个程序集?

As far as I know, the framework uses AssemblyVersion, Name and PublicKeyToken to identify the assembly.据我所知,该框架使用 AssemblyVersion、Name 和 PublicKeyToken 来标识程序集。

My local assembly (working):我的本地程序集(工作):

Assembly Location: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
Assembly Fullname: System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
File ProductVersion: 10.0.14393.1532
File Size: 7,1MB

Server assembly (not working):服务器组件(不工作):

Assembly Location: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
Assembly Fullname: System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
File ProductVersion: 6.3.9600.18728
File Size: 5,8MB

The two files are indisputably different.这两个文件无疑是不同的。 But according to AssemblyName they are identical.但根据 AssemblyName,它们是相同的。 This way the framework will load one or the other.这样框架将加载一个或另一个。

How can it be that two apparently different files (even by just looking at the file's size) have the same AssemblyName?两个明显不同的文件(即使仅查看文件的大小)怎么可能具有相同的 AssemblyName?

I'd like to add that the target machine is a Windows Server 2012R2, but it is not the only one where I noticed this.我想补充一点,目标机器是 Windows Server 2012R2,但它并不是我注意到这一点的唯一机器。 I have also noticed it on a freshly installed Windows 7 and another Windows 2012 Server.我还在新安装的 Windows 7 和另一个 Windows 2012 服务器上注意到了它。

I ended up using the official Powershell reference asseblies packages on NuGet and lived happy ever after.我最终在 NuGet 上使用了官方的 Powershell 参考组件包,从此过上了幸福的生活。 Too keep it compatible as much as possible I now almost always use Microsoft.PowerShell.3.ReferenceAssemblies .尽可能地保持兼容我现在几乎总是使用Microsoft.PowerShell.3.ReferenceAssemblies No more issues since.从那以后就没有问题了。

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

相关问题 在开发计算机上安装.NET 4.5.2会导致System.Management.Automation.dll错误 - Installing .NET 4.5.2 on development machine causes error with System.Management.Automation.dll 如何强制从具有PowerShell 3.0版的计算机上加载System.Management.Automation.dll v1.0? - How do I force a load of System.Management.Automation.dll v1.0 from a machine that has PowerShell version 3.0 on it? System.Management.Automation中没有PowerShell? - No PowerShell in System.Management.Automation? 命名空间“System.Management”中缺少自动化。 缺少装配参考 - Missing Automation from namespace 'System.Management'. Missing assembly reference .NET Core,Windows Nano Server和System.Management.Automation - .NET Core, Windows Nano Server and System.Management.Automation 如何在 .NET Framework 4.7.2 中引用 System.Management.Automation? - How to reference System.Management.Automation in a .NET Framework 4.7.2? DNX的ASP.NET 5 MVC 6 System.Management.Automation问题 - ASP.NET 5 MVC 6 System.Management.Automation issue with DNX 无法调用System.Management.Automation.Runspaces.WSManConnectionInfo - Unable to Call System.Management.Automation.Runspaces.WSManConnectionInfo 从 System.Management.Automation 调用脚本时未设置 $PSScriptRoot - $PSScriptRoot not set when invoking script from System.Management.Automation 引用DLL,编译,DLL版本控制 - Referencing DLL, Compiling, DLL versioning
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM