windows 我如何(有没有办法)将 HRESULT 转换为系统特定的错误消息?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4597932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:54:26  来源:igfitidea点击:

How can I (is there a way to) convert an HRESULT into a system specific error message?

c++windowswinapi

提问by Billy ONeal

According to this, there's no way to convert a HRESULT error code into a Win32 error code. Therefore (at least to my understanding), my use of FormatMessage in order to generate error messages (i.e.

根据这个,没有办法到HRESULT错误代码转换为Win32错误代码。因此(至少据我所知),我使用 FormatMessage 来生成错误消息(即

std::wstring Exception::GetWideMessage() const
{
    using std::tr1::shared_ptr;
    shared_ptr<void> buff;
    LPWSTR buffPtr;
    DWORD bufferLength = FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetErrorCode(),
        0,
        reinterpret_cast<LPWSTR>(&buffPtr),
        0,
        NULL);
    buff.reset(buffPtr, LocalFreeHelper());
    return std::wstring(buffPtr, bufferLength);
}

) does not work for HRESULTs.

) 不适用于 HRESULT。

How do I generate these kinds of system-specific error strings for HRESULTs?

如何为 HRESULT 生成这些类型的特定于系统的错误字符串?

回答by Mordachai

This answer incorporates Raymond Chen's ideas, and correctly discerns the incoming HRESULT, and returns an error string using the correct facility to obtain the error message:

这个答案结合了 Raymond Chen 的想法,并正确识别传入的 HRESULT,并使用正确的工具返回错误字符串以获取错误消息:

/////////////////////////////
// ComException

CString FormatMessage(HRESULT result)
{
    CString strMessage;
    WORD facility = HRESULT_FACILITY(result);
    CComPtr<IErrorInfo> iei;
    if (S_OK == GetErrorInfo(0, &iei) && iei)
    {
        // get the error description from the IErrorInfo 
        BSTR bstr = NULL;
        if (SUCCEEDED(iei->GetDescription(&bstr)))
        {
            // append the description to our label
            strMessage.Append(bstr);

            // done with BSTR, do manual cleanup
            SysFreeString(bstr);
        }
    }
    else if (facility == FACILITY_ITF)
    {
        // interface specific - no standard mapping available
        strMessage.Append(_T("FACILITY_ITF - This error is interface specific.  No further information is available."));
    }
    else
    {
        // attempt to treat as a standard, system error, and ask FormatMessage to explain it
        CString error;
        CErrorMessage::FormatMessage(error, result); // <- This is just a wrapper for ::FormatMessage, left to reader as an exercise :)
        if (!error.IsEmpty())
            strMessage.Append(error);
    }
    return strMessage;
}