从 dll 的字节数组加载程序集
Loading an assembly from a dll's Byte array
我正在尝试使用此加载程序集:
$pathToDll = "C:\zip\SevenZipSharp.dll"
$pathTo7zDll = "C:\zipz.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
它工作正常。
如果我从字节数组加载程序集,为什么会抛出异常?
编辑:
我想使用字节数组加载它的原因是因为如果我使用 Add-Type
它似乎保留了 .dll 的句柄并且我以后无法使用 Remove-Item
删除它。
编辑: 这有效:
[System.Configuration.ConfigurationManager]::AppSettings["7zLocation"] = $pathToDll
调用前需要先调用[SevenZip.SevenZipExtractor]::SetLibraryPath($pathTo7zDll)
我相信您 运行 遇到了 .NET 的基本限制。一旦程序集加载到您的应用程序域中,就不会卸载该 dll。您需要使用程序集中的类型还是仅对其进行反思?如果是后者,可以把DLL加载到一个reflection-only context.
库正在使用反射通过 Assembly.GetExecutingAssembly().Location
找到自己的路径,并用这个值初始化一些静态字段。 See the source code:
private static string _libraryFileName = ConfigurationManager.AppSettings["7zLocation"] ??
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll");
但是,如果直接从字节数组加载程序集,Location 为空,GetDirectoryName 将抛出异常。这不是 PowerShell 的限制,而是库的问题。
可能有一个解决方法,即加载 System.Configuration 并在尝试加载库之前设置 7zLocation 应用设置。
由于库似乎试图让您通过 SetLibraryPath
设置路径,这可能是一个错误,应报告给维护者。
我正在尝试使用此加载程序集:
$pathToDll = "C:\zip\SevenZipSharp.dll"
$pathTo7zDll = "C:\zipz.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
它工作正常。
如果我从字节数组加载程序集,为什么会抛出异常?
编辑:
我想使用字节数组加载它的原因是因为如果我使用 Add-Type
它似乎保留了 .dll 的句柄并且我以后无法使用 Remove-Item
删除它。
编辑: 这有效:
[System.Configuration.ConfigurationManager]::AppSettings["7zLocation"] = $pathToDll
调用前需要先调用[SevenZip.SevenZipExtractor]::SetLibraryPath($pathTo7zDll)
我相信您 运行 遇到了 .NET 的基本限制。一旦程序集加载到您的应用程序域中,就不会卸载该 dll。您需要使用程序集中的类型还是仅对其进行反思?如果是后者,可以把DLL加载到一个reflection-only context.
库正在使用反射通过 Assembly.GetExecutingAssembly().Location
找到自己的路径,并用这个值初始化一些静态字段。 See the source code:
private static string _libraryFileName = ConfigurationManager.AppSettings["7zLocation"] ??
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll");
但是,如果直接从字节数组加载程序集,Location 为空,GetDirectoryName 将抛出异常。这不是 PowerShell 的限制,而是库的问题。
可能有一个解决方法,即加载 System.Configuration 并在尝试加载库之前设置 7zLocation 应用设置。
由于库似乎试图让您通过 SetLibraryPath
设置路径,这可能是一个错误,应报告给维护者。