2015-05-13 3 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."

Однако, если я заменю [System.Reflection.Assembly]::Load($dllByteArray) с

Add-Type -path $pathToDll 

все нормально работает.

Почему он бросает исключение, если я загружаю сборку из массива Byte?

EDIT: Поэтому я хочу, чтобы загрузить его, используя массив байт, потому что, если я использую Add-Type, кажется, держать ручку на .dll и я не могу удалить его с помощью Remove-Item позже.

EDIT: Это сработало:

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

Это должно быть вызван перед вызовом [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. После того, как сборка загружена в ваш домен приложения, разгрузка этой DLL не будет. Вам нужно использовать тип сборки или просто задуматься над ним? Если это последний, вы можете загрузить DLL в reflection-only context.

+0

Но почему это бросает исключение, когда я вызываю [SevenZip.SevenZipExtractor] :: SetLibraryPath ($ pathTo7zDll)? –

+0

Я предполагаю, что загружаемая сборка зависит от другой сборки, которая не может быть найдена. Сначала попробуйте загрузить недостающую сборку. Вам нужно вникнуть в подробности этого исключения - искать его InnerException и проверять его - рекурсивно до тех пор, пока InnerException не станет нулевым. –

Смежные вопросы