无法从COM客户端实例化DLL中的2个类中的1个
本文关键字:2个 1个 中的 DLL COM 客户端 实例化 | 更新日期: 2023-09-27 18:16:03
我正在使用一个主要用c#编写的。net 4应用程序。应用程序有一个用户界面,但它也有一个自动化界面,允许从. net客户端直接利用应用程序的特性。它还支持通过COM实现自动化,因此有"COM适配器"dll以COM友好的方式在"真正的"dll中呈现类/方法。
例如,让我们说API的大部分功能是在一个名为"Alpha.DLL"的DLL中:一个。net客户端可以简单地直接引用该DLL,但一个名为"Alpha.Com.DLL"的单独DLL提供给COM客户端(例如VBA)使用。
有3个这样的COM适配器dll,虽然两个工作得很好,但我根本无法使最后一个正常工作。
问题DLL中只定义了两个类,虽然我可以从COM客户端(如VBScript)实例化其中一个,但当我尝试实例化另一个时,我会得到一个错误。我得到的错误是:
-2146234304 (0x80131040) Automation Error
我可以从。net代码实例化同一个类,而不是从COM客户端。
我已经尝试使用FUSLOGVW.EXE来查找程序集加载错误,但似乎没有任何(并且在任何情况下,我可以实例化来自同一DLL的其他类的事实表明,它不是DLL本身无法找到/加载?)。
我试过附加一个调试器,并在构造函数中为违规类设置一个断点,但当我试图从VBScript实例化类时,它不会被击中。(工作的类的构造函数中的断点不会命中)。
我已经检查了我试图实例化的类的注册表项,我看不到任何问题。guid和版本号似乎都匹配。
我已经无计可施了,如果你能帮助我,我将非常感激。
-2146234304 (0x80131040) Automation Error
在像VBA这样的COM客户端中使用。net代码的常见问题是。net异常很难诊断。您必须使用通常是神秘的HRESULT错误代码,您没有获得Holy Stack跟踪来查看代码是如何爆炸的。这个异常很奇怪,它是FUSION_E_REF_DEF_MISMATCH,您可以在CorError.h SDK包含文件中找到这些HRESULT代码。
你通常会得到更容易解释的异常消息"定位程序集的清单定义不匹配程序集引用"。堆栈跟踪告诉你是什么类型导致了这个异常,这样你就知道是哪个程序集出了问题。当从VBA调用失败时,没有类似的结果。
这是一个日常的。net事故,CLR发现你的程序集,但它的[AssemblyVersion]不匹配参考程序集的版本,你的代码被编译。COM当然会增加出错的几率,当您使用Regasm.exe注册程序集时,版本会记录在注册表中。如果您手工重新注册,而不是让构建系统来处理,那么忘记重新注册是一个非常容易的疏忽。也很容易复制依赖dll在客户端EXE的目录,所以CLR可以找到他们,而忘记更新他们。
Fuslogvw.exe 显示了这种不幸,很难猜测为什么你没有看到任何东西。备份计划使用SysInternals的Process Monitor。它还向您展示了客户端如何读取注册表,这是COM中经常出错的另一个问题。你会看到它从注册表项定位DLL,所以你可以猜测为什么它找到了一个旧的。
使用GAC来避免麻烦,这通常是帮助CLR找到相关程序集和解决COM相当严重的DLL地狱问题所必需的。并且强烈考虑使用。net 4 AppDomain。FirstChanceException事件。最好在COM客户端无法诊断异常之前记录异常。
请先检查
- 你的com dll被放入GAC
- 你别忘了回归http://www.jagjot.com/2014/01/register-c-vb-net-dll-regasm-gacutil/
- 检查cpu架构
- 你的com dll依赖于GAC以外的任何东西吗?
啊哈。我找到了问题所在。我在问题中说:
我已经检查了我试图实例化的类的注册表项,我看不到任何问题。guid和版本号似乎都匹配。
…这是真的。然而,我没有注意到的是,在我的一个类的的注册表定义中,公钥令牌是错误的。
这解释了为什么一个类可以被实例化,而另一个不能,并且可能在FUSLOGVW日志中没有任何内容(因为当"好"类的实例被创建时,程序集被正常加载)。
谢谢你们的帮助,Hans和Dimzon。