我正在使用库SharpShell开发一个简单的shell扩展(属性表)来显示.NET程序集的一些信息,请参阅:
这个shell扩展和SharpShell本身与这个问题无关,但是为了解释我的场景,你可以更好地理解我的问题。
我的项目被编译为任何CPU模式,然后,为了管理x86的加载,x64我程序中的任何CPU程序集我正在使用函数Assembly.Load()
的重载,它将原始程序集的字节作为唯一参数:
Assembly asm = Assembly.Load( File.ReadAllBytes(filepath) );
我使用d86和x86和x64架构的可执行文件以及任何CPU测试它,它工作正常......除了我将解释的问题。
问题是,由于某种原因,我忽略它不适用于某些x86程序集,例如当我尝试加载x86程序集:System.Web.dll(System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
)时,Assembly.Load()
函数抛出异常。它不是一个BadImageException
,它是一个带有此错误消息的FileLoadException
:
无法加载文件或程序集'System.Web,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'或其依赖项之一。给定的程序集名称或代码库无效。 (HRESULT异常:0x80131047)
(请注意,Assembly.ReflectionOnlyLoad()
也会抛出相同的异常。)
但是,我可以成功加载同一程序集的x64版本。请注意,正如我所说的,我可以在程序中加载大多数32位程序集。
如果我将我的项目编译为x86,那么我可以使用sucess加载这个程序集。但我的项目必须编译为任何CPU(能够处理x86和x64程序集的加载......因为我不知道更好的方法)。
我想知道为什么我无法加载特定的程序集,以及解决此问题的可行方法。
如果你想测试它,你可以在这里下载dll:
http://www.mediafire.com/file/8h9256w02b2j3dj/System.Web.dll.zip/file
与使用Assembly.Load()
的当前进程相比,无法为不同的处理器体系结构加载程序集。
请改用Assembly.ReflectionOnlyLoadFrom()
。
在一个运行为64位的简单演示应用程序中,我看到以下行为:
var lAss = Assembly.Load(File.ReadAllBytes(@"C:\Windows\Microsoft.NET\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll"));
MessageBox.Show(lAss.Location);
这会抛出问题中描述的异常。
var lAss = Assembly.ReflectionOnlyLoadFrom((@"C:\Windows\Microsoft.NET\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll"));
MessageBox.Show(lAss.Location);
这不会抛出任何异常并显示消息框。