微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我正在使用 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,我将开始在DLL_ATTACH中放置OutputDebugString,当有人尝试调用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

doing so introduces a CLR version dependency which may conflict with the CLR version expected by the host process

这种失败模式也在an article on MSDN when using COM wrappers中注明;您可以在其中指定clrVersion:

If another version of the CLR is already loaded and the specified version can be loaded side-by-side in-process,the specified version is loaded; otherwise,the loaded CLR is used. This might cause a load failure.

如果这是Windows XP上的间歇性加载失败的原因,或者.NET框架上的先前版本,我该如何获取mscoree.dll来告诉我?

如果原因是别的,我该如何让.NET告诉我?

解决方法

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

此外,即使您不能在同一进程中加载​​多个.NET VM,通过使用App.config和.dll清单进行一些手动工作,您也可以将.dll加载到同一个.NET VM中,即使它们是针对不同的。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐