【问题标题】:Type.GetType returns null when called via COM interopType.GetType 在通过 COM 互操作调用时返回 null
【发布时间】:2014-12-30 15:56:25
【问题描述】:

我有包含 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#

返回空值

两种情况下的程序集限定名称相同。

如果我启动程序集 A 不是作为 COM 对象而是作为来自托管进程的常规程序集,则 Type.GetType 在两种情况下都有效:在 A 启动代码和 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

有什么想法吗?

【问题讨论】:

    标签: .net com-interop


    【解决方案1】:

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

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

    【讨论】:

    • 几分钟前我发现 AppDomain.CurrentDomain.AssemblyResolve 解决了问题 :) 不过还是谢谢。
    • 嗯,水晶球确实在低语“他没有研究他的问题,别打扰”。无论如何欢迎您。
    • 我之前不知道加载上下文...这阻止了我对装配位置的实验。我确定 - 如果加载了 A,那么无论如何都可以找到它。
    猜你喜欢
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 2012-02-01
    • 2011-11-18
    相关资源
    最近更新 更多