我有程序集 A,其中包含 CustomSettings 提供程序 MySettingProvider。该程序集由 native 进程创建为 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) Line 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
有什么想法吗?
最佳答案
我的 Crystal 球说 Type.GetType(string) 返回 null,因为您没有执行任何操作来帮助 CLR 找到包含 MySettingProvider
类的程序集。这是必需的,CLR 本身没有太多机会找到它。您可以通过将程序集复制到与“native.exe”相同的目录中来快速自行测试,这样它就位于探测路径中。
当然,这是一个完全不合适的解决方案,[ComVisible] 程序集无法选择使用它的应用程序类型。您需要通过将您拥有的任何依赖项存储在 GAC 中来提供帮助。 GAC 也是主程序集所在的地方,它是解决 COM 的 DLL Hell 问题的一个很好的解决方案。无论如何,在用户的机器上,可以通过复制文件的方式在自己的机器上进行测试。您也许可以让 AppDomain.AssemblyResolve 工作,但您需要一个像 Application 这样的“全局”对象,以确保您及时注册事件处理程序。
关于.net - 通过 COM 互操作调用时,Type.GetType 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27708517/