“班级未注册”哪一类?

时间:2009-06-02 12:20:29

标签: c++ com atl

考虑以下代码:

try {
    ISomeObject pObj(__uuidof(SomeClass));
    ISomeObject pObj2(__uuidof(SomeOtherClass));
} catch ( _com_error& e ) {
    // Log what failed
}

即。我有一块代码可以实现我的对象。 有时(安装不好)它会因为某些课程没有正确注册而失败。 (我没有特别的问题,而是这里的一般性讨论。)

是否有某种方法可以从捕获的异常或其他方面了解哪个类失败了? A考虑制作一个我自己的包装器,它存储一个像 gLastCreateAttemptUuid 这样的变量,但感觉很麻烦。

另外,假设SomeClass反过来试图实现其他未注册的东西。那么人们可以找出潜在的问题吗?

3 个答案:

答案 0 :(得分:1)

CComPtr::CreateInstance nor _com_ptr_t::CreateInstance should throw an exception from what I can tell from the documentation. Both return an HRESULT value.

nor CoCreateInstance should throw an exception from what I can tell from the documentation. Both return an HRESULT value.

But if you check the HRESULT return value from each call, you should be able to determine which of the two classes are not registered (if that is the problem).

try {
    ISomeObject pObj, pObj2;
    HRESULT hr1 = pObj.CreateInstance(__uuidof(SomeClass));
    HRESULT hr2 = pObj2.CreateInstance(__uuidof(SomeOtherClass));
} catch ( _com_error& e ) {
    // Log what failed
}
无法返回值。

更新:如果您发现异常,请向我们展示其所拥有的任何信息。如果是这种情况,那么我的猜测是你试图实例化的一个类是抛出错误。调试这些行或将代码分成两个try / catch块将帮助您缩小哪一个异常没有任何信息。

答案 1 :(得分:0)

CoCreateInstance()调用者有责任提供有关它试图实例化的内容的足够信息 - ATL和Native COM Support都没有内置的功能。

不是调用使用类id参数化的智能指针构造函数,而是可以调用其CreateInstance()方法 - 它具有完全相同的参数集,但不会抛出异常。然后你可以检查HRESULT并处理错误并提供你刚用于错误处理程序的类id。

但是,如果问题发生在您无法控制的代码中,则无法帮助。在极端情况下,您可以使用Process Monitor来监视注册表查询并检测导致问题的类ID。

答案 2 :(得分:0)

我经常使用自己的CoCreateInstance()函数包装器,这样如果调用失败,我可以尝试使用CLSID从注册表中查找ProgID。这样我至少可以将CLSID放入异常字符串中,但希望能做得更好。我也为接口执行此操作,因为注册表中的接口IID的默认字符串通常是人类可读的名称。查看:: StringFromGUID2()以格式化GUID。

当然,这无助于您以任何方式处理第三方依赖。为此,我会选择sharptooth对ProcessMonitor的建议(或者是它的堂兄RegMon)。

相关问题