关于COM错误代码的最佳信息来源是什么?

时间:2020-03-05 18:50:06  来源:igfitidea点击:

当我们只有HRESULT时,我不知所措,无法获得关于含义,可能的原因以及解决COM错误的可能解决方案的最佳信息。

在Google中搜索" 80004027"之类的词几乎是无用的,因为它将我们带到随机讨论组中,在90%的情况下,问题是" 80004027是什么意思?"没有答案。

对此有什么好的资源? MSDN为什么不是Google的最高成绩?

解决方案

回答

COM错误代码的结构

在Google搜索结果中排第二位,显示COM错误代码。

回答

来自Prakash的良好链接(我不知道RCNr的内容,我认为这些字节是该功能的一部分,但这似乎只适用于16位Windows。)

这些未知代码通常是特定于我们正在使用的接口/组件的。该功能将设置为FACILITY_ITF。我有一个解析HRESULT的旧程序HRPlus(链接?)。

回答

%PROGRAMFILES%[Visual Studio的某些版本] \ Tools Common7 \文件夹中的错误查找(ErrLook.exe)会经常(但并非总是)显示错误消息:

|---------------------------------------------------|
    | [] Error Lookup                                   |
    |---------------------------------------------------|
    |   Value: [0x80004027]                             |
    |                                                   |
    |   Error Message                                   |
    |   +---------------------------------------------+ |
    |   |The component or application containing the  | |
    |   |component has been disabled                  | |
    |   |                                             | |
    |   +---------------------------------------------+ |
    |   [Modules...]    [Look up]    [Close]    [Help]  |
    |----------------------------------------------------

如果这不起作用,那么我们可以从此处遵循一些想法:
http://blogs.msdn.com/oldnewthing/archive/2008/09/01/8914664.aspx

(错误查找仅使用FORMAT_MESSAGE_FROM_SYSTEM调用FormatMessage()
旗帜)

如果COM错误不是系统错误,则可能还必须检查引发该错误的组件的文档。

如果我们在代码中捕获错误,则可以希望该组件实现大量错误(GetErrorInfo(),与VB中的Err对象相同),以便获得描述问题的完整消息。

回答

我总是使用WinError.h。那具有绝大多数Windows错误代码。

需要注意的关键指标是代码的Facility部分:第二个最高有效字节。也就是说,为0x80nnmmmm,其中nn为设施。告诉我们哪个组件生成了代码。设施为7的任何东西都是Windows错误代码,将其重新包装为HRESULT,我们应该将低位字转换为十进制,然后在WinError.h中查找它。在它们自己的标题中也存在错误范围(例如,从12000 12999开始的任何内容都是WinInet错误代码,我们应该在WinInet.h中进行查找)。

查找错误代码将为我们提供符号名称,该符号名称可能会在代码本身或者错误消息的措辞之外的更多文档中找到。

FACILITY_ITF(其值为4,因此这些HRESULT以0x8004开头)表明该错误是由我们所使用的接口定义的;我们必须检查该界面以了解其含义。

最后,COM还提供接口IErrorInfo来检索扩展的错误信息:调用GetErrorInfo来检索错误对象。我们必须查询ISupportErrorInfo并调用该接口的InterfaceSupportsErrorInfo方法,以确定我们调用的接口是否实际设置了错误对象(当然,如果它是模板代码,则可能是在撒谎)。