加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 10:18:08 所属栏目:大数据 来源:网络整理
导读:我正在使用 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); 其实我在Del
我正在使用 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事件查看器,看看是否有任何记录。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读