在x64位操作系统上,从“任意CPU”构建的应用程序中反思x86汇编

3
我有一个编译为“任何 CPU”的.Net应用程序。我在x64操作系统上运行它,因此它以64位运行。该应用程序加载用户提供的其他程序集。它当然使用反射从用户提供的程序集中读取类型。如果用户程序集是作为“任何 CPU”编译的,则一切正常。但是,如果该程序集被编译为x86,则我会在反射时收到“这不是Win32应用程序”异常。很明显,这是由于主机应用程序正在以64位运行所致。
我的问题是,如何解决这个问题?有什么想法吗?
谢谢
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);
    }

0

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


0

如果您只需要用于反射目的,可以使用Mono.Cecil,我认为这应该可以很好地处理它。

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

第一种方法更好且更快, 仅用于反射,从不想要实例化类型,但固有更多的努力。第二个容易出错(dll可能依赖于未管理的代码,当通过反射扫描触发时,无论如何都会失败。

作为解决此问题的第三个备选方案。只需强制您的应用程序仅以32位运行,那么它应该可以正常加载所有内容。你真的需要运行64位吗?


如果我运行32位,那么我将遇到与64位程序集相关的问题,这也是我的情况。我可以尝试使用ReflectionOnly进行加载,看看是否有效。我所需要做的就是反射程序集以读取类型。我实际上并不执行任何操作。嗯...我需要查找属性,所以这可能是一个问题,因为查找属性会执行它:/ - Nazeeh
在我的经验中,只有64位的.Net程序集非常罕见,它们几乎总是混合模式。你可能正在使用需要它们的工作,但请考虑是否有必要费心。读取类型/属性是Cecil将为您完成的工作,因此我建议您采用这种方法... - ShuggyCoUk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接