我正在尝试使用以下方法加载程序集:
$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)
答案 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。