[英]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.