如何获取OLE对象异常中FACILITY_CONTROL类HRESULT的错误文本?
获取FACILITY_CONTROL类型HRESULT的错误文本
问题描述
调用OLE对象的IDispatch::Invoke()时,从EXCEPINFO结构得到HRESULT错误码0x800A0034,对应错误文本应为“Bad file name or number”,但使用带FORMAT_MESSAGE_FROM_SYSTEM参数的FormatMessage()无法获取到该文本,示例代码如下:
int main() { HRESULT hr = 0x800A0034; LPWSTR lpMsgBuf = nullptr; DWORD dwChars = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, hr, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), reinterpret_cast<LPWSTR>( &lpMsgBuf ), 0, nullptr ); if ( dwChars > 0 ) { std::wcout << L"Error message: " << lpMsgBuf << std::endl; } else { std::cerr << "Failed to get error message for HRESULT " << hr << std::endl; } LocalFree( lpMsgBuf ); return 0; }
该HRESULT属于FACILITY_CONTROL设施,对应OleCtl.h中定义的错误码52(CTL_E_BADFILENAMEORNUMBER),需要找到Windows运行时获取这类错误消息文本的方法。
解决方案
这类OLE控件相关的错误消息不在系统默认消息资源中,而是存储在oleaut32.dll里,需修改FormatMessage()的调用方式,指定从该DLL加载消息资源:
- 先加载
oleaut32.dll模块 - 调用
FormatMessage()时传入该模块句柄,用FORMAT_MESSAGE_FROM_HMODULE参数替代FORMAT_MESSAGE_FROM_SYSTEM
修改后的示例代码:
#include <windows.h> #include <iostream> int main() { HRESULT hr = 0x800A0034; LPWSTR lpMsgBuf = nullptr; // 加载oleaut32.dll HMODULE hOleAut32 = LoadLibraryW(L"oleaut32.dll"); if (hOleAut32 == nullptr) { std::cerr << "Failed to load oleaut32.dll" << std::endl; return 1; } DWORD dwChars = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, hOleAut32, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&lpMsgBuf), 0, nullptr); if (dwChars > 0) { std::wcout << L"Error message: " << lpMsgBuf << std::endl; } else { std::cerr << "Failed to get error message for HRESULT " << std::hex << hr << std::endl; } // 释放资源 LocalFree(lpMsgBuf); FreeLibrary(hOleAut32); return 0; }
说明
FACILITY_CONTROL对应的错误消息资源存放在oleaut32.dll中,必须指定该模块句柄才能正确获取文本- 通过
LoadLibraryW加载oleaut32.dll后,将其作为FormatMessage的第二个参数传入 - 使用
FORMAT_MESSAGE_FROM_HMODULE参数,指示从指定模块加载消息资源
内容的提问来源于stack exchange,提问作者Carl
相关产品推荐
相关产品推荐

