3

我有一个编译为“任何 CPU”的 .Net 应用程序。我在 x64 操作系统上运行它,所以它以 64 位运行。应用程序加载用户提供的其他程序集。它当然使用反射从用户提供的程序集中读取类型。如果用户程序集被编译为“任何 CPU”,则一切正常。但是如果程序集编译为 x86,我会在反射时得到“这不是 Win32 应用程序”异常。这显然是由于主机应用程序运行 64 位。

我的问题是,我该如何解决这个问题?有什么想法/想法吗?

谢谢

4

3 回答 3

6

好的。我想到了。对于我的目的,这只是对程序集的简单类型发现,但没有实例化,如果程序集是 32 位,则使用 Assembly.ReflectionOnlyLoad 可以工作。

您使用 Assembly.ReflectionOnlyLoad 加载程序集,并允许您反映类型。您也应该挂钩到 AppDomain.CurrentDomain.ReflectionOnlyLoadResolve。

要获取属性名称,您需要在类型、方法或模块上使用 CustomAttributeData.GetCustomAttributes。

 static void Main(string[] args)
    {
        AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
        Assembly assm = Assembly.ReflectionOnlyLoadFrom("TestProject1.dll");

        Type t = assm.GetType("TestProject1.ProgramTest");
        MethodInfo m = t.GetMethod("MainTest");

        IList<CustomAttributeData> data = CustomAttributeData.GetCustomAttributes(t);


    }

    static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
    {
        return Assembly.ReflectionOnlyLoad(args.Name);
    }
于 2009-06-11T19:50:07.510 回答
0

您可以复制文件并更改位。

于 2009-06-11T17:51:11.730 回答
0

如果您只需要出于反射目的加载它,您可以使用Mono.Cecil,我认为它应该没问题。

或者,获取 dll 的副本,对文件运行 corflags 以翻转仅 32 位标志,然后加载副本。

第一个对于反射来说更好更快,从不想实际实例化一个类型,但本质上需要更多的努力。第二个是容易出错的(dll 可能依赖于非托管代码,当通过反射扫描触发时,无论如何都会失败。

作为回避该问题的第三种替代选择。只需强制您的应用程序仅以 32 位运行,然后它应该可以正常加载所有内容。你真的必须运行64位吗?

于 2009-06-11T18:03:43.540 回答