繁体   English   中英

System.Management.Automation.dll 版本混淆

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

我有一个“核心”程序集,其中包含一系列用 C# 编写的 PowerShell Cmdlet。 我还有一个使用这个“核心”程序集的 WPF“gui”应用程序。 为了使用和编译“核心”,我显然需要 PowerShell 的类型,因此我在我的项目中添加了对System.Management.Automation.dll的引用。 我通过简单地从我的本地机器 GAC 添加对该 DLL 的引用来做到这一点。 一切都在我的机器上编译并顺利运行。

当我在另一台机器上部署和运行我的“gui”时,出现奇怪的错误。 例如:

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

我已将原因缩小到这一点:我的“gui”实现了一个自定义 PowerShell 主机并加载“核心”并执行它的 cmdlet。 它是这样完成的:

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

显然,在运行时找不到属性PsInstance.Streams.Information

我发现作为项目引用添加的System.Management.Automation.dll不一定是加载的那个。 该框架首先查看 GAC,如果在那里找到副本,它会使用该副本而不是我的副本。

我知道问题的原因是部署机器安装了旧版本的 PowerShell,它没有实现我正在使用的属性 - 并抛出上述异常。

然而,我不明白的是:当它与我构建的程序集不兼容时,框架如何从 GAC 加载这个程序集?

据我所知,该框架使用 AssemblyVersion、Name 和 PublicKeyToken 来标识程序集。

我的本地程序集(工作):

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

服务器组件(不工作):

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

这两个文件无疑是不同的。 但根据 AssemblyName,它们是相同的。 这样框架将加载一个或另一个。

两个明显不同的文件(即使仅查看文件的大小)怎么可能具有相同的 AssemblyName?

我想补充一点,目标机器是 Windows Server 2012R2,但它并不是我注意到这一点的唯一机器。 我还在新安装的 Windows 7 和另一个 Windows 2012 服务器上注意到了它。

我最终在 NuGet 上使用了官方的 Powershell 参考组件包,从此过上了幸福的生活。 尽可能地保持兼容我现在几乎总是使用Microsoft.PowerShell.3.ReferenceAssemblies 从那以后就没有问题了。

暂无
暂无

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

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