无法从COM客户端实例化DLL中的2个类中的1个

时间:2014-07-31 17:56:50

标签: c# .net com com-interop

我正在使用主要使用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和版本号似乎都匹配。

我完全没有想法,在我的系绳结束时,我非常感谢你的帮助......

3 个答案:

答案 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)

请先检查

  1. 您的所有内容已放入GAC
  2. 你不要忘记regasm http://www.jagjot.com/2014/01/register-c-vb-net-dll-regasm-gacutil/
  3. 检查cpu架构
  4. 你的com是否取决于GAC以外的任何内容?

答案 2 :(得分:0)

Aaargh。我发现了这个问题。我在问题中说:

  

我已经检查了我试图实例化的类的注册表项,我看不出任何问题。 GUID和版本号似乎都匹配。

......这是真的。但是,我没有注意到的是,在我的类的一个的注册表定义中,公钥令牌是错误的。

这解释了为什么一个类可以实例化而另一个类不能实例化,也可能为什么FUSLOGVW日志中没有任何内容(因为在创建" good"类的实例时,组件已加载正常)。

感谢您的帮助,Hans和Dimzon。

相关问题