2009-06-11 204 views
3

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

我的问题是,我该如何解决这个问题?任何想法/想法?

谢谢

回答

0

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

0

如果你只是为了反思的目的而加载它,你可以使用Mono.Cecil,我认为它应该没问题。

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

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

作为第三个替代选项来避开这个问题,只需强制您的应用运行作为32位只,然后它应该加载一切就好了你真的真的必须运行64位?

+0

如果我运行32位,我会碰到64位程序集的问题,这也是我的情况。 我可能会尝试使用ReflectionOnly加载并查看是否有效。我所需要做的只是在程序集上反映读取类型。我实际上没有执行任何操作。嗯...我需要查看属性,所以这可能是一个问题,因为查看它执行它:/ – Nazeeh 2009-06-11 19:23:36

+0

只有64位.Net程序集在我的经验中非常罕见,它们几乎总是混合模式。你可能正在使用它们的工作,但考虑是否需要打扰。阅读类型/属性是塞西尔会为你做的事情,所以我建议你去那条路线... – ShuggyCoUk 2009-06-12 11:05:50

5

好吧,我想通了,这只是一个简单类型发现的程序集,但没有实例化,如果程序集是32位,则使用Assembly.ReflectionOnlyLoad工作

使用Assembly.ReflectionOnlyLoad加载程序集并允许您使用r反映在类型上。您也应该挂钩到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); 
    } 
相关问题