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

Ian*_*oyd 35 .net delphi com ccw com-callable-wrapper

我使用以下命令创建一个COM对象(来自本机代码)CoCreateInstance:

const 
   CLASS_GP2010: TGUID = "{DC55D96D-2D44-4697-9165-25D790DD8593}";

hr = CoCreateInstance(CLASS_GP2010, nil, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, out unk);
Run Code Online (Sandbox Code Playgroud)

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

CreateComObject(CLASS_GP2010);
Run Code Online (Sandbox Code Playgroud)

大部分时间这个功能都成功了.但有时,在同一个可执行文件中,在同一进程中,调用CoCreateInstance失败的原因是:

Unspecified error (0x80004005 = E_FAIL)
Run Code Online (Sandbox Code Playgroud)

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

这不是我的COM dll

如果这是一个正常的 COM DLL,我写,我就开始把OutputDebugStringDLL_ATTACH,当有人试图打电话DllGetClassObject,我会确认COM是正确加载我的DLL,并且它被正确要求被实例化的类.

不幸的是,它不是COM dll; 它是一个.NET程序集dll.COM子系统并不是简单地 "加载"我的dll.相反,COM被指示加载mscoree.dll:

HKEY_CLASSES_ROOT
   CLSID
      {DC55D96D-2D44-4697-9165-25D790DD8593}
         InprocServer32
            @default = mscoree.dll
Run Code Online (Sandbox Code Playgroud)

mscoree.dll导出所需的GetClassObject功能.那mscoree.dll个人回来了E_FAIL,不是我.故障永远不会发生在我的开发机器上,但始终在客户机器上间歇性地失败.

如何启用.NET日志记录?

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

例如,似乎唯一遇到故障的客户(除了是唯一大量使用COM对象的客户)恰好在Windows XP上.也许他们遇到了.NET框架中的已知错误(版本4之前),您无法在同一进程中加载​​不同版本的.NET运行时:

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

使用COM包装器时,MSDN上的一篇文章中也提到了这种失败模式.您可以选择指定clrVersion:

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

如果这我在Windows XP上的间歇性加载失败的原因,或者是.NET框架上的早期版本,我怎么能mscoree.dll告诉我这个?

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

Ara*_*ion 0

至少,如果您要在 Visual Studio 的调试器中运行它,您可能能够捕获第一次机会的异常并获得一些见解。至少,您想知道哪种错误会导致 E_FAIL。即使您没有调试符号,您也应该能够执行此操作。

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

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