如果 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(类未注册异常)

微信支付url未注册问题