PowerShell二进制模块程序集依赖性错误

时间:2015-09-04 12:52:59

标签: c# json powershell .net-assembly

我正在开发 PowerShell二进制模块。它使用Json.NET和其他库。

我收到此异常“无法加载文件或程序集'Newtonsoft.Json,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = 30ad4fe6b2a6aeed'或其中一个依赖项。系统找不到指定的文件。'< / p>

在硬盘上我有它的更新版本(版本7.0.2)

这样的问题很容易在控制台,网络或桌面应用程序中解决,通过 app.config 或“web.config”通过这样的行

<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二进制模块执行类似的操作?

4 个答案:

答案 0 :(得分:4)

在开发使用多个第三方库(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文件加载)

要在任何cmd中使用它,请在PSCmdLet的BeginProcessing()方法中添加以下事件处理程序。

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_BindingRedirect;

答案 1 :(得分:2)

到目前为止,我发现的最接近的是:

  1. 将问题程序集添加到清单的RequiredAssemblies中 - 这会导致在加载模块时将其加载到AppDomain中。
  2. 使用this SO answer中的代码 - 它将AssemblyResolve处理程序添加到当前AppDomain,后者搜索已加载的程序集并返回按强名称和PublicKeyToken匹配的程序集
  3. 使用该模块后,您必须执行以下操作以避免在退出时出现堆栈溢出:remove.packages('fpp') remove.packages('rmarkdown') install.packages('fpp') install.packages('rmarkdown') install.packages('survival') install.packages('forecast') library(fpp) library(rmarkdown) library(survival) library(forecast) plot(naive(train, h=h))
  4. 步骤1和2都可以封装在模块中,但步骤3不能,这意味着这不适合作为一般解决方案 - 调用者必须知道它。所以我还在寻找更好的方法。

答案 2 :(得分:0)

您需要在模块中添加manifest

最简单的方法是:

New-ModuleManifest -RequiredAssemblies:"path\to\newtonSoft.dll"

然后手动修改清单文件以进行任何其他调整。

如果清单无法解决问题,您可能需要拔出核锤并为Powershell - Assembly binding redirect NOT found in application configuration file

中提到的所有powershell设置绑定重定向

答案 3 :(得分:0)

对于二进制模块,需要在清单文件中填充一些密钥才能成功导入/功能:

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

......应该这样做。