从“任何 CPU”反射 x86 程序集 在 x64 位操作系统上构建应用程序
我有一个编译为“任何 CPU”的 .Net 应用程序。 我在 x64 操作系统上运行它,因此它以 64 位运行。 应用程序加载用户提供的其他程序集。 当然,它使用反射来从用户提供的程序集中读取类型。 如果用户程序集被编译为“任何 CPU”,则一切正常。 但如果程序集编译为 x86,我会在反射时收到“这不是 Win32 应用程序”异常。 这显然是因为主机应用程序运行的是 64 位。
我的问题是,我该如何解决这个问题? 有什么想法/想法吗?
谢谢
I have a .Net app that's compiled as "Any CPU". I am running it on a x64 OS so it's running as 64bit. The application loads other assemblies that the user provides. It uses reflection of course to read types from the user provided assembly. Everything works fine if the user assembly is compiled as "Any CPU". But if the assembly is compiled as x86, I get the "this is not a Win32 application" exception at reflection time. It's obviously due to the fact that the host app is running 64bit.
My question is, how can I work around this? Any thoughts/ideas?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的。 我想到了。 出于我的目的,这只是程序集的简单类型发现,但没有实例化,如果程序集是 32 位,则使用 Assembly.ReflectionOnlyLoad 可以工作。
您可以使用 Assembly.ReflectionOnlyLoad 加载程序集,并且可以反映类型。 您还应该挂钩 AppDomain.CurrentDomain.ReflectionOnlyLoadResolve。
要获取属性名称,您需要在类型、方法或模块上使用 CustomAttributeData.GetCustomAttributes。
Ok. I figured it out. For my purposes, which were just a simple type discovery for an assembly but no instantiation, using Assembly.ReflectionOnlyLoad works if the assembly is 32bit.
You load the assembly with Assembly.ReflectionOnlyLoad and you are allowed to reflect on the types. You should hook to the AppDomain.CurrentDomain.ReflectionOnlyLoadResolve as well.
To get Attribute names, you need to use CustomAttributeData.GetCustomAttributes on a type, method or module.
您可以复制该文件并更改位。
You could copy the file and change the bit.
如果您只需要加载它用于反射目的,您可以使用我认为的 Mono.Cecil应该没问题。
或者,获取 dll 的副本,对文件运行 corflags 以翻转仅 32 位标志,然后加载副本。
第一个要好得多 更快只是为了反映,从不想实际实例化类型,但本质上需要更多努力。 第二个是容易出错的(dll 可能依赖于非托管代码,当通过反射扫描触发时,无论如何都会失败。
作为第三个替代选项来回避这个问题。只需强制您的应用程序仅以 32 位运行,那么它应该可以正常加载所有内容。您真的必须运行 64 位吗?
If you only need to load it for reflective purposes you can use the Mono.Cecil which I think should be fine with it.
Alternatively grab a copy of the dll, run corflags against the file to flip the 32bit only flag and then load the copy.
The first is much better and faster for just reflecting, never wanting to actually instantiate a type but inherently more effort. The second is error prone (the dll may have dependencies on unmanaged code which, when triggered via the reflection scan, will fail no matter what.
As a third, alternate option to sidestep the issue. Just force your app to run as 32bit only, then it should load everything just fine. Do you really have to run 64bit?