“类未注册” 是哪个类未注册?

3

考虑以下代码:

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

比如说我有一段代码块可以实例化我的对象。有时(安装不良)会失败,因为某个类没有正确注册。(我没有特别的问题,这里只是一般讨论。)

是否有一种方法可以从捕获的异常或其他方式中意识到是哪个类出现了问题?我考虑过制作自己的包装器,存储像 gLastCreateAttemptUuid 这样的变量,但感觉很麻烦。

此外,假设 SomeClass 尝试实例化其他未注册的类,那么能否找出潜在问题?

3个回答

1

CoCreateInstance()的调用方有责任提供足够的关于其尝试实例化的信息 - ATL和Native COM Support都没有内置的功能来完成这一点。

与调用带有类ID参数的智能指针构造函数不同,您可以调用它的CreateInstance()方法 - 它具有完全相同的一组参数,但不会抛出异常。然后,您可以检查HRESULT并处理错误,并将刚使用的类ID提供给错误处理程序。

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


1

根据文档,CComPtr::CreateInstance_com_ptr_t::CreateInstance都不应该抛出异常。两者都返回HRESULT值。

但是,如果你检查每个调用的HRESULT返回值,你应该能够确定哪个类没有注册(如果这是问题的原因)。

try {
    ISomeObject pObj, pObj2;
    HRESULT hr1 = pObj.CreateInstance(__uuidof(SomeClass));
    HRESULT hr2 = pObj2.CreateInstance(__uuidof(SomeOtherClass));
} catch ( _com_error& e ) {
    // 记录失败信息
}

请查看CoCreateInstance的文档以获取返回值。

更新:如果你正在捕获一个异常,请展示出它所包含的任何信息。如果是这种情况,那么我的猜测是你尝试实例化的其中一个类抛出了错误。在这些代码行上进行调试或将代码分成两个try/catch块可以帮助你缩小范围,以确定哪一个是异常没有任何信息的原因。


_com_error被捕获的事实意味着OP没有使用ATL,而是使用了“内置COM支持”(_com_ptr_t),如果我没记错的话。 - C. K. Young

0

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

当然,这并不能帮助您以任何方式处理第三方依赖项。对于此,我会选择sharptooth的建议ProcessMonitor(或其较旧的表兄RegMon)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接