如果 com dll 未注册,如何防止崩溃
Posted
技术标签:
【中文标题】如果 com dll 未注册,如何防止崩溃【英文标题】:How to prevent crashing if com dll isnt registered 【发布时间】:2009-01-27 12:48:25 【问题描述】:从我尝试使用 com dll 的一些旧 c++ 代码中,当 dll 注册时它工作正常,但如果 dll 未注册,它会崩溃。
// 初始化 COM。 HRESULT hr = CoInitialize(NULL);
IGetTestPtr ptest(__uuidof(tester));
“使用 dll 中的方法”
// 取消初始化 COM。 CoUninitialize();
是否在调用 IGetTestPtr ptest(__uuidof(tester)) 之前检查 dll 是否已注册?
或者防止崩溃的正确方法是什么?
【问题讨论】:
【参考方案1】:在您的对象上调用 CreateInstance 将返回一个可以测试是否成功的 HRESULT:
IGetTestPtr p = null;
HRESULT hRes = p.CreateInstance( __uuidof(tester) );
bool bSuccess = SUCCEEDED(hRes);
这假设您已经使用 Visual Studio 在类型库周围创建了一个接口包装器,其中在接口中使用了 COM 智能指针(这为您提供了 CreateInstance 方法)。
【讨论】:
您将 .Net 的 COM 互操作与本机 C++ COM 混淆了。你认为哪个对象实现了 CreateInstance 方法? @Stu - 我大致基于我不久前在调用 C++ COM 对象的 C++ MFC 应用程序中编写的代码。我认为我不会混淆 .NET 互操作,但可以想象我会混淆 C++ 框架。我会进一步调查并更新我的答案。 此答案和 OP 问题均使用 Microsoft 编译器对 COM 的支持。它不是 MFC 或 ATL(或直接 SDK),而是从 VC++ 使用 COM 的另一种方式。当您看到 #import 预处理器指令时,您就知道您正在使用它。这不是 .NET! 我个人讨厌这个框架,它与其他 COM 框架是多余的,隐藏了重要的细节,并且编写了一些看起来很奇怪的代码(属性??WTF??)。请给我 CoCreateInstance... 好的 - 我已经纠正了。它似乎只是在导入的接口周围创建智能指针包装器。如果没有要导入的类型库怎么办?【参考方案2】:如果 DLL 已注册,HKCR/CLSID/uuidof(tester)
中有一条记录(大括号很重要)。
实际上,如果不是,那么CoCreateInstance
将返回错误。在使用指针之前检查这个错误。
【讨论】:
不要依赖内部实现,即注册表项。 Microsoft 可以随时更改。【参考方案3】:如果未注册 COM 类,则 CoCreateInstance 将返回 REGDB_E_CLASSNOTREG。您应该使用 SUCCEEDED() 或 FAILED() 宏检查一般成功或失败。您还需要正确创建对象 - 请参阅 MDSN 以获取 introduction to COM。例如:
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
IGetTestPtr ptr = NULL;
hr = CoCreateInstance(CLSID_MyObjectNULL, CLSCTX_INPROC_SERVER, IID_IMyInterface, ptr)
if (SUCCEEDED(hr))
Do something with your COM object
...
// Don't forget to release your interface pointer or the object will leak
ptr->Release();
hr = CoUninitialize();
return hr;
【讨论】:
【参考方案4】:如果我没记错的话,这个“#import”风格的 COM 框架会引发异常。在代码周围添加一个 try-catch 块。 Google 告诉我例外是 _com_error 类型的。
除非您在 #import 上调整参数以防止这种情况发生,否则所有失败的 COM 调用都会引发异常。您将不得不关闭它(我认为#import "raw" 接口可以做到这一点 - 查看#import 文档)或真正熟悉这些异常。
【讨论】:
以上是关于如果 com dll 未注册,如何防止崩溃的主要内容,如果未能解决你的问题,请参考以下文章
通过注册的 TLB 从 python 访问未注册的 COM 对象
如何在vb6中注册一个不能用作com互操作的.net DLL?
初始化 VCProjectEngineObject (Microsoft.VisualStudio.VCProjectEngine.dll) 时出现错误 80040154(类未注册异常)