2017-02-28 103 views
2

我見過幾個類似的問題,但沒有解決我的問題。場景是 - 我有外部存儲器中的幾個DLL,我需要獲得關於它們的信息(Assembly版本和AssemblyInformationalVersion是特定的)。我從下面的代碼開始:將程序集加載到臨時應用程序域

List<byte[]> assemblies = _client.DownloadAllAssemblies(); 
foreach(var assemblyBytes in assemblies) 
{ 
    var assembly = Assembly.ReflectionOnlyLoad(assemblyBytes); 
    var assemblyName = assembly.GetName(); 
    ... // read version from assembly name 
} 

上面的代碼只工作一次。如果我點擊一個按鈕來刷新視圖 - 它會拋出異常說組件已經加載並且無法重新加載它。然後我讀到,我應該創建臨時域並加載程序集,以便在完成後卸載AppDomain。我嘗試下面的代碼:

List<byte[]> assemblies = _client.DownloadAllAssemblies(); 
var tempDomain = AppDomain.Create("TemporaryDomain"); 
foreach(var assemblyBytes in assemblies) 
{ 
    var assembly = tempDomain.Load(assemblyBytes); 
    var assemblyName = assembly.GetName(); 
    ... // read version from assembly name 
} 
AppDomain.Unload(tempDomain); 

上面的代碼拋出FileNotFound異常說「無法加載文件或程序......」

我明白爲什麼它正在發生,但我不知道如何來解決此。任務似乎很簡單:

  1. 加載文件,
  2. 閱讀它的版本,
  3. 忘掉它。

上面的邏輯沒有什麼複雜的。看起來像運行時需求過於複雜。有誰知道我怎麼能使它工作?

+0

需要更多的堆棧跟蹤(總是提供完整的信息)有可能在加載任何傳入的字節數組之前,依賴程序集無法加載。您應從「應用程序域」複製某些屬性默認,如探測路徑。你還想使用'ReflectionOnlyLoad',它不會試圖解決所有問題。 –

+0

@ escape-llc AppDomain不公開「ReflectionOnlyLoad」函數。稍後我會用StackTrace更新問題。謝謝。 – MajkeloDev

回答

2

任務看起來並不平凡。 AppDomain.Load方法不打算以這種方式使用它。

System.AppDomain類的Load方法可以加載程序集,但主要用於COM互操作性。它不應該用於將程序集加載到除調用它的應用程序域之外的應用程序域中。

我看到了兩個解決方案,以你的情況:

  1. 簡單方法。將彙編字節數組寫入臨時文件,並通過FileVersionInfo.GetVersionInfo讀取其FileVersionProductVersion。在大多數情況下,這些值應與AssemblyVersionAssemblyInformalVersion中的值相同。

  2. 使用AppDomain的正確方法。應用程序域的問題在於,您要加載的程序集應該從該域內部加載,而不是在外部加載。

要做到這一點,你需要創建一個包含所有必要的邏輯特殊類和類,應參照被編組(從MarshalByRef類繼承它)。

然後,在創建新域後,您應該將該類加載到新創建的域中並將其解包。你可以用CreateInstanceAndUnwrap方法做到這一點。

這個類將生活在另一個領域,並給它的方法和屬性的所有呼叫都將被整理到該域,所以你可以用你的邏輯來加載組件和閱讀必要的信息。或者在其他域中做任何其他的東西。

完成後,您可以並應該卸載該域。

不要忘記,最初的應用程序域是完全空的,所以當你創建任何類的實例或加載額外的程序集時.net應該解析並加載所有相關的程序集到該域中。有時系統無法自動執行此操作,但在這種情況下,您可以通過訂閱新域的AssemblyResolve事件來幫助系統執行此操作。

+0

感謝您的回覆。如果「AppDomain.Load方法不打算以這種方式使用它。」那麼我不想「誤用」它。我會嘗試臨時下載解決方案,並讓你知道是否成功。我有一個控制DLL創建(他們是在網站上創建和編譯),所以我應該能夠設置FileVerison,所以它將等於AssemblyVersion。 – MajkeloDev

+0

我結束了steve16351的解決方案http://stackoverflow.com/questions/26106431/loading-byte-array-assembly-into-new-appdomain-throws-a-filenotfound-exception/26107788?noredirect=1#comment72198604_26107788 – MajkeloDev

相關問題