繁体   English   中英

Powershell 配置程序集重定向

[英]Powershell config assembly redirect

我有一个自定义 .NET 程序集,其中包含一些 powershell cmdlet,而不是用于常见域相关任务。 我刚刚创建了一个新的 cmdlet,它引用了一个 3rd 方库,该库引用了 Newtonsoft.Json 4.5.0.0。 然而,我的其他项目之一使用最新版本的 json.net (6.0.0.0)。 所以在 powershell fusion 运行时抛出一个错误,说它无法加载 newtonsoft.json 4.5.0.0。

我试过创建一个 powershell.exe.config 并在那里放置一个程序集重定向:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json", Culture=neutral,     PublicKeyToken=30ad4fe6b2a6aeed/>
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

但这似乎不起作用。 融合日志确实指出它正在查看这个新的 powershell 配置文件,但它似乎没有选择重定向。

有点难住这里的解决方案。 任何线索可能是什么问题? 这个相同的重定向适用于我的一些业务服务,否则会出现相同的问题(他们也使用这个 3rd 方库和 json.net 6)。

干杯

不确定它比一年前是如何工作的,但是今天在使用 PowerShell 5.0.10240.16384 的 Windows 10 上,我能够进行程序集重定向(在我的情况下从FSharp.Core 4.3 到 4.4)的唯一方法是手动解决基于在 PowerShell 中手动解析程序集依赖项 我尝试了所有其他解决方案,例如创建powershell.exe.config文件或尝试加载其他一些*.config file ,但没有任何效果。

唯一的“问题”(至少对我来说)是,因为我在任何地方都没有FSharp.Core 4.3,我需要手动将它重定向到 4.4。 我最终使用

$FSharpCore = [reflection.assembly]::LoadFrom($PSScriptRoot + "\bin\LIBRARY\FSharp.Core.dll") 

$OnAssemblyResolve = [System.ResolveEventHandler] {
  param($sender, $e)

  # from:FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  # to:  FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  if ($e.Name -eq "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") { return $FSharpCore }
  
  foreach($a in [System.AppDomain]::CurrentDomain.GetAssemblies())
  {
    if ($a.FullName -eq $e.Name)
    {
      return $a
    }
  }
  return $null
}

[System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve)

我首先从某个地方加载正确版本的FSharp.Core ,因为 GAC 中的版本很旧(我想这也可能是你的情况)

您还可以 在我的项目中查看真实的测试使用情况

我发现尝试使用[System.AppDomain]::CurrentDomain.add_AssemblyResolve解析 PowerShell 中附加的处理程序会导致问题,尤其是在 PowerShell ISE 中。

或者,这可以通过实现IModuleAssemblyInitializer接口在根模块程序集(包含PSCmdlet类)中IModuleAssemblyInitializer

以接受的答案为例,它可以重写为:

public class ModuleInitializer : IModuleAssemblyInitializer
{
    public void OnImport()
    {
        var fSharpCore = Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "FSharp.Core.dll"));

        AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs e) =>
        {
            // from:FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
            // to:  FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
            if (e.Name == "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") { return fSharpCore; }

            foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (a.FullName == e.Name)
                {
                    return a;
                }
            }

            return null;
        };
    }
}

在我的例子中,我使用这种机制来查找伴随的.dll.config并根据dependentAssembly/bindingRedirect元素重定向。

暂无
暂无

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

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