如何诊断COM可调用包装器对象创建失败?

时间:2013-07-24 14:19:21

标签: .net delphi com ccw com-callable-wrapper

我正在使用CoCreateInstance

创建一个COM对象(来自本机代码)
const 
   CLASS_GP2010: TGUID = "{DC55D96D-2D44-4697-9165-25D790DD8593}";

hr = CoCreateInstance(CLASS_GP2010, nil, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, out unk);

实际上,我在Delphi中,这意味着我调用了辅助函数:

CreateComObject(CLASS_GP2010);

大部分时间此功能成功。但有时,在相同的可执行文件中,在同一进程中,对CoCreateInstance的调用失败并显示:

Unspecified error (0x80004005 = E_FAIL)

再次调用该函数可能会成功,或者可能会失败。没有(明显的)押韵或理由。

这不是我的COM dll

如果这是我写的正常 COM dll,我会开始在OutputDebugString中放置DLL_ATTACH,当有人试图拨打DllGetClassObject时,我将确认COM正确加载我的DLL,并且它正确地要求实例化类。

不幸的是,它不是COM dll;它是一个.NET程序集dll。 COM子系统does not simply “加载”我的dll。相反,COM被指示加载mscoree.dll

HKEY_CLASSES_ROOT
   CLSID
      {DC55D96D-2D44-4697-9165-25D790DD8593}
         InprocServer32
            @default = mscoree.dll

mscoree.dll导出所需的GetClassObject函数。所以mscoree.dll是返回E_FAIL的人,而不是我。故障永远不会发生在我的开发机器上,但始终在客户机器上间歇性地失败。

如何启用.NET日志记录?

问题是,因为mscoree.dll是返回E_FAIL的那个(而不是任何有用的东西):我如何告诉我这是什么问题?

例如,似乎唯一遇到故障的客户(除了是唯一大量使用COM对象的客户)恰好是在Windows XP上。也许他们遇到了.NET框架中的已知错误(版本4之前)cannot load different versions of the .NET runtime into the same process

  

这样做会引入CLR版本依赖性,这可能与主机进程期望的CLR版本冲突

这种失败模式也在an article on MSDN when using COM wrappers中注明;你有选项指定clrVersion

的地方
  

如果已经加载了另一个版本的CLR并且可以在进程中并行加载指定的版本,则加载指定的版本;否则,使用加载的CLR。这可能会导致负载故障。

如果 导致我在Windows XP上的间歇性加载失败,或者.NET框架上的早期版本,我怎样才能让mscoree.dll告诉我?< / p>

如果原因是别的,我怎么让.NET告诉我?

2 个答案:

答案 0 :(得分:0)

至少,如果您要在Visual Studio的调试器中运行它,您可能能够捕获第一次机会异常并获得一些洞察力。至少,您想知道E_FAIL中会出现什么样的错误。即使您没有调试符号,也应该能够这样做。

此外,即使您无法在同一进程中加载​​多个.NET VM,也可以使用App.config和.dll清单进行一些手动操作,您也许可以在同一个.NET VM中加载.dll即使它们是针对不同的编译而来的。

最后,检查应用程序事件下的Windows事件查看器,看看是否有任何记录。

答案 1 :(得分:0)

您可以使用程序集绑定失败日志记录功能 - 需要启用它,然后您可以使用fusion日志查看器查看结果 http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.110).aspx 不知道如何将这个装到你的客户机器上。

当我第一次阅读本文时,我的第一个想法是在win xp box上看起来最常见的是这个.net版本/位智能问题,或者你的.net dll缺少这些机器上没有的依赖项。