2015-05-13 23 views
2

我想以此來加載程序集的程序集:加載DLL中的字節數組

$pathToDll = "C:\zip\SevenZipSharp.dll" 
$pathTo7zDll = "C:\zip\7z.dll" 
$dllByteArray= [System.IO.File]::ReadAllBytes($pathToDll) 
[System.Reflection.Assembly]::Load($dllByteArray) 

然而,這並不拋出異常時,我想使用的庫SevenZip.SevenZipExtractor這樣的:

[SevenZip.SevenZipExtractor]::SetLibraryPath($pathTo7zDll) 

它說:Exception calling "SetLibraryPath" with "1" argument(s): "The type initializer for 'SevenZip.SevenZipLibraryManager' threw an exception."

但是如果我有

更換
Add-Type -path $pathToDll 

它工作正常。

爲什麼它會拋出異常,如果我從字節數組加載程序集?

編輯: 我想用一個字節數組加載它的原因是因爲如果我使用Add-Type似乎繼續該.dll手柄和後面使用Remove-Item我不能刪除它。

編輯:這工作:調用[SevenZip.SevenZipExtractor]::SetLibraryPath($pathTo7zDll)

回答

2

庫正在使用Reflection通過Assembly.GetExecutingAssembly().Location找到自己的路徑並使用該值初始化一些靜態字段。 See the source code

private static string _libraryFileName = ConfigurationManager.AppSettings["7zLocation"] ?? 
     Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll"); 

但是,如果直接從字節數組加載程序集,該位置是空和GetDirectoryName會拋出異常。它不是PowerShell的限制,它是庫的問題。

可能有一個可能的解決方法,那就是加載System.Configuration並在嘗試加載庫之前設置7zLocation應用程序設置。

由於庫似乎試圖讓你通過SetLibraryPath設置路徑,這可能是一個錯誤,應該向維護者報告。

0

我相信你正在運行到.NET的基本限制之前

[System.Configuration.ConfigurationManager]::AppSettings["7zLocation"] = $pathToDll 

需要被調用。一旦程序集加載到您的應用程序域中,就不會卸載該dll。你需要使用組件中的類型還是僅僅反思它?如果是後者,則可以將DLL加載到reflection-only context中。

+0

但是爲什麼當我調用[SevenZip.SevenZipExtractor] :: SetLibraryPath($ pathTo7zDll)時拋出Exception? –

+0

我的猜測是被加載的程序集依賴於另一個無法找到的程序集。嘗試首先加載缺失的程序集。您需要深入瞭解該異常的細節 - 查找它的InnerException並檢查它 - 遞歸直到InnerException爲null。 –