PowerShell二进制模块组件依赖错误
本文关键字:依赖 错误 组件 模块 二进制 PowerShell | 更新日期: 2023-09-27 18:11:07
我正在开发PowerShell二进制模块它使用Json。. NET和其他库
我得到这个异常"无法加载文件或程序集"Newtonsoft。Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'或其依赖项之一。系统找不到指定的文件
在硬盘上我有一个更新的版本(版本7.0.2)
这样的问题很容易在控制台,web或桌面应用程序中解决,使用应用程序。配置或"web. conf"。通过这样的行配置
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
如何为PowerShell二进制模块做类似的事情?
在开发使用多个第三方库(Google API, Dropbox, Graph等)的PowerShell模块时遇到了这个问题,我发现以下解决方案是最简单的:
public static Assembly CurrentDomain_BindingRedirect(object sender, ResolveEventArgs args)
{
var name = new AssemblyName(args.Name);
switch (name.Name)
{
case "Microsoft.Graph.Core":
return typeof(Microsoft.Graph.IBaseClient).Assembly;
case "Newtonsoft.Json":
return typeof(Newtonsoft.Json.JsonSerializer).Assembly;
case "System.Net.Http.Primitives":
return Assembly.LoadFrom("System.Net.Http.Primitives.dll");
default:
return null;
}
}
注意,在方法中,我有两种可能的方法来引用程序集,但它们都做同样的事情,它们强制使用该程序集的当前版本。(不管它是通过类引用还是通过dll文件加载)
要在任何命令行中使用它,请在PSCmdLet的BeginProcessing()方法中添加以下事件处理程序。
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_BindingRedirect;
目前为止我发现最接近的是:
- 将问题程序集添加到manifest的RequiredAssemblies中——这会导致它在加载模块时被加载到AppDomain中。
- 使用这个SO答案中的代码-它向当前的AppDomain添加了一个AssemblyResolve处理程序,该处理程序搜索已经加载的程序集并返回通过强名称和PublicKeyToken匹配的程序集
- 使用模块后,您必须做以下操作以避免退出时堆栈溢出:
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($OnAssemblyResolve)
步骤1和步骤2都可以封装在模块中,但步骤3不能,这意味着这不适合作为通用解决方案-调用者必须知道它。所以我还在寻找一个更好的方法。
你需要在你的模块中添加一个清单。
最简单的方法是:
New-ModuleManifest -RequiredAssemblies:"path'to'newtonSoft.dll"
然后手动修改manifest文件以进行任何其他调整。
如果清单不能解决问题,您可能需要拉出核锤并为所有powershell设置绑定重定向,如powershell - Assembly绑定重定向中提到的在应用程序配置文件
对于二进制模块,为了成功导入/功能,需要在manifest文件中填充一些键:
RootModule = <'binaryModule.dll'>
RequiredAssemblies = <'binaryModule.dll'>
CmdletstoExport = '*' <--no need to restrict anything here, as
only the public functions you've developed in the assembly
will be exported to the user.
这些是您需要为模块"工作"填充的唯一键-尽管我强烈建议通过New-ModuleManifest -path MyNewModule.psd1
生成的.psd1文件来梳理其他元数据值,以帮助丰富模块的功能。
另外,确保目录结构、.psd1文件和程序集的名称都是一致的。
SampleModule'
SampleModule'SamleModule.dll
SampleModule'SampleModule.psd1
…应该可以了