2015-09-04 27 views
4

我正在開發PowerShell二進制模塊。它使用Json.NET和其他庫。PowerShell二進制模塊組件依賴錯誤

我得到這個異常「無法加載文件或程序集'Newtonsoft.Json,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = 30ad4fe6b2a6aeed'或它的某個依賴項,系統找不到指定的文件。

在硬盤驅動器我有一個更新版本的它(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的二進制模塊類似的東西?

回答

0

你需要一個manifest添加到您的模塊。

最簡單的方法是:

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

然後手動修改清單文件用於其他任何調整。

如果清單不解決這個問題,您可能需要爲Powershell - Assembly binding redirect NOT found in application configuration file

+0

我使用了所需的程序集,但沒有奏效。我通過畫廊提供我的模塊,我不能要求所有用戶調整他們的PowerShell全局配置文件,即使我的PC在本地也不會這樣做。 – TIKSN

+0

這個問題涉及綁定重定向。清單中的RequiredAssemblies鍵告訴powershell要加載的程序集,但不允許綁定重定向。 – ben

0

對於二進制模塊提到拉出核錘,並設置綁定重定向爲所有的PowerShell的,有幾個關鍵的是 - 雖然我強烈建議通過生成的.psd1文件梳理

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到其他元數據值將有助於豐富fu你的模塊的功能。

此外,請確保目錄結構,.psd1文件和程序集的名稱都是一致的。

SampleModule\ 
SampleModule\SamleModule.dll 
SampleModule\SampleModule.psd1 

......應該這樣做。

+0

我的問題不是如何加載類型或程序集,我的問題很熱重定向程序集版本。 – TIKSN

2

最近我到目前爲止發現的是:

  1. 問題組件添加到清單的RequiredAssemblies - 這將導致加載模塊,當它被加載到應用程序域。
  2. 使用從this SO answer代碼 - 它增加了一個AssemblyResolve處理當前的AppDomain中,其搜索已加載的程序集和強名稱和公鑰
  3. 返回那些其符合使用該模塊後,你必須做以下避免堆棧溢出退出時:

步驟1和2可以既在模塊中被封裝,但在步驟3不能,這意味着這是不適合作爲一般的解決方案 - 呼叫者必須知道關於它。所以我仍在尋找更好的方法。

+0

感謝您的回答,但我認爲這不是一個好的解決方案。請讓我知道你是否想出了更好的解決方案。我仍在尋找解決方案。 – TIKSN

+0

我同意這不是一個好的解決方案。我認爲堆棧溢出是由調用'[System.AppDomain] :: CurrentDomain.GetAssemblies()'引起的。您可以通過在您的事件處理程序腳本中對要解析的特定程序集進行硬編碼(在上面的步驟2中),併爲其他所有內容返回null來避免此問題。現在我已經用一種不同的方式避免了這個問題 - 對我來說,System.Reactive需要在.NET4.6中綁定重定向,但是通過降級到.NET4.5.2,問題消失了。 – ben

3

過這個問題,今後自己在開發使用多個第三方庫一個PowerShell模塊(谷歌API,Dropbox的,圖形等)後,我發現下面的解決方案是最簡單的:

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-let中使用此項,請在PSCmdLet的BeginProcessing()方法中添加以下事件處理程序。

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_BindingRedirect;