我正在使用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,我会开始在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
的人,而不是我。故障永远不会发生在我的开发机器上,但始终在客户机器上间歇性地失败。
问题是,因为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告诉我?
答案 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缺少这些机器上没有的依赖项。