我正在使用以下命令创建一个 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);
实际上,我在 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 子系统不会简单地 “加载”我的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 之前)中的已知错误,您无法将不同版本的 .NET 运行时加载到同一进程中:
这样做会引入一个 CLR 版本依赖关系,它可能与宿主进程期望的 CLR 版本冲突
在使用 COM 包装器时,MSDN 上的一篇文章中也提到了这种故障模式;您可以选择指定 a clrVersion
:
如果已经加载了另一个版本的 CLR,并且可以在进程中并行加载指定的版本,则加载指定的版本;否则,使用加载的 CLR。这可能会导致加载失败。
如果这是我在 Windows XP 或 .NET 框架上的早期版本中间歇性加载失败的原因,我该如何mscoree.dll
告诉我呢?
如果原因是其他原因,我如何让 .NET 告诉我?