从dll的Byte数组加载程序集

时间:2015-05-13 00:48:23

标签: powershell dll .net-assembly 7zip

我正在尝试使用以下方法加载程序集:

$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数组加载程序集,为什么会抛出异常?

修改 我想使用Byte数组加载它的原因是因为如果我使用Add-Type它似乎保留了.dll的句柄,我以后不能使用Remove-Item删除它。< / p>

编辑:这有效:

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

在调用[SevenZip.SevenZipExtractor]::SetLibraryPath($pathTo7zDll)

之前需要调用它

2 个答案:

答案 0 :(得分: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");

但是,如果直接从字节数组加载程序集,则Location为null,GetDirectoryName将引发异常。它不是PowerShell的限制,它是库的一个问题。

可能有一种可能的解决方法,即在尝试加载库之前加载System.Configuration并设置7zLocation应用程序设置。

由于库似乎试图让你通过SetLibraryPath设置路径,这可能是一个错误,应该向维护者报告。

答案 1 :(得分:0)

我相信你遇到了.NET的一个基本限制。将程序集加载到您的应用程序域后,就不会卸载该DLL。您是否需要使用装配中的类型或仅反映它?如果是后者,则可以将DLL加载到reflection-only context