通过COM互操作调用时,Type.GetType返回null

时间:2014-12-30 15:56:25

标签: .net com-interop

我有一个包含CustomSettings提供程序MySettingProvider的程序集A.此本程序集由本机进程创建为COM对象,然后CLR尝试使用Type.GetType调用按名称解析提供程序类型。

如果我尝试直接在A:

的启动代码中解析类型
var aqn = typeof(MySettingProvider).AssemblyQualifiedName;
var providerType = Type.GetType(aqn);

这有效。

但由于某种原因,从系统程序集调用了Type.GetType:

  

System.dll!System.Configuration.ApplicationSettingsBase.CreateSetting(System.Reflection.PropertyInfo propInfo)第426行C#

返回null

装配合格的名称在两种情况下都相同。

如果我启动程序集A不是作为COM对象而是作为来自托管进程的常规程序集,那么Type.GetType在两种情况下都有效:在启动代码和System.Configuration.ApplicationSettingsBase中。

如果我再添加一个嵌套级别并尝试在程序集B中创建类型,它也可以。

一些'图片'使用调用堆栈:

native.exe
  -> COM interop
    -> A.dll
      -> Type.GetType: OK
      -> B.dll
        -> Type.GetType: OK
      -> System.Configuration.ApplicationSettingsBase
        -> Type.GetType: null

managed.exe
  -> A.dll
    -> Type.GetType: OK
    -> B.dll
      -> Type.GetType: OK
    -> System.Configuration.ApplicationSettingsBase
      -> Type.GetType: OK

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我的水晶球说Type.GetType(string)返回null,因为你没有做任何事情来帮助CLR找到包含你的MySettingProvider类的程序集。这是必需的,CLR本身并没有多大机会找到它。您可以通过将程序集复制到与“native.exe”相同的目录中来自行快速测试,以便它位于探测路径中。

当然,这是一个完全不合适的解决方案,[ComVisible]程序集无法选择使用哪种应用程序。您需要通过存储GAC中的任何依赖项来提供帮助。也是主要程序集所在的位置,GAC是COM的DLL Hell问题的一个很好的解决方案。无论如何,在用户的机器上,您可以通过复制文件在自己的机器上进行测试。您可能能够使AppDomain.AssemblyResolve工作,但您需要一个像Application这样的“全局”对象,以确保您及时注册事件处理程序。