我正在使用主要使用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和版本号似乎都匹配。
我完全没有想法,在我的系绳结束时,我非常感谢你的帮助......
答案 0 :(得分:3)
-2146234304 (0x80131040) Automation Error
使用来自COM客户端(如VBA)的.NET代码的常见问题是.NET异常很难诊断。你必须使用一个经常神秘的HRESULT错误代码,你没有获得Holy Stack跟踪来查看代码如何爆炸。这个异常就像那样,它是FUSION_E_REF_DEF_MISMATCH,你可以在CorError.h SDK包含文件中找到这些HRESULT代码。
您通常可以更容易地解释异常消息“找到的程序集的清单定义与程序集引用不匹配”。并且堆栈跟踪告诉您导致此异常的类型,以便您知道哪个程序集是问题。当从VBA调用此失败时,没有类似的东西。
这是一个日常的.NET事故,CLR找到了你的程序集,但它的[AssemblyVersion]与编译代码的引用程序集的版本不匹配。 COM肯定会增加这可能出错的几率,当您使用Regasm.exe注册程序集时,版本会记录在注册表中。忘记重新注册,如果你手工完成而不是让构建系统处理它是一个非常容易的疏忽。也很容易在客户端EXE的目录中复制相关的DLL,因此CLR可以找到它们,并忘记更新它们。
Fuslogvw.exe 确实显示了这种不幸,很难猜到为什么你什么也看不见。备份计划是使用SysInternals的Process Monitor。它还向您展示了客户端如何读取注册表,这是COM中经常出现的另一个问题。并且您将看到它从注册表项中找到DLL,因此您将有机会猜测它为何找到旧的。
通过使用GAC避免麻烦,无论如何通常都需要帮助CLR找到依赖程序集并解决COM相当严重的DLL Hell问题。并强烈考虑使用.NET 4 AppDomain.FirstChanceException事件。很高兴在COM客户端变为不可识别之前记录异常。
答案 1 :(得分:1)
请先检查
答案 2 :(得分:0)
Aaargh。我发现了这个问题。我在问题中说:
我已经检查了我试图实例化的类的注册表项,我看不出任何问题。 GUID和版本号似乎都匹配。
......这是真的。但是,我没有注意到的是,在我的类的一个的注册表定义中,公钥令牌是错误的。
这解释了为什么一个类可以实例化而另一个类不能实例化,也可能为什么FUSLOGVW日志中没有任何内容(因为在创建" good"类的实例时,组件已加载正常)。
感谢您的帮助,Hans和Dimzon。