返回
解决 C++ WMI 枚举和获取实例方法失败的问题
windows
2024-03-10 23:39:55
解决 C++ WMI 枚举和获取实例方法失败的问题
简介
在尝试使用 C++ WMI 查找和设置新创建的 VHD 磁盘时,您可能遇到错误 HRESULT 0x8004101e,这表明您使用了错误的根目录或其他问题。本文将深入探讨这个问题,提供循序渐进的解决方法,并提供一个经过修复的代码示例。
问题根源
WMI 故障可能有多种原因,包括:
- 使用了错误的根目录或其他命名空间
- 无法获取方法接口
- 方法名或参数签名不正确
- 权限不足
- 防火墙设置阻碍连接
解决方法
解决此问题需要以下步骤:
1. 验证 WMI 连接
- 确保使用正确的根目录路径:
ROOT\\cimv2\\storage
2. 检查方法可用性
- 尝试使用
GetMethod
方法获取方法接口,如果失败,表明方法不可用。
3. 确定正确的方法名
- 对于
Format
方法,使用以下名称:_bstr_t methodName(L"Format");
4. 检查参数签名
- 确保方法调用的参数签名与所需的参数匹配。
5. 确保权限
- 以具有适当权限(如管理员权限)的帐户运行代码。
6. 检查防火墙设置
- 确保防火墙未阻止 WMI 连接。
修复后的代码示例
以下是修改后的代码示例:
int main() {
int ret = -2;
try {
CComPtr<IWbemLocator> wbemLocator;
CComPtr<IWbemServices> wbemServices;
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr))
throw std::runtime_error("Failed to initialize COM");
// flag COM as initialized
ret = -1;
// Set general COM security levels --------------------------
hr = CoInitializeSecurity(NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL); // Reserved
if (FAILED(hr))
throw std::runtime_error("Failed to initialize security");
// Obtain the initial locator to WMI -------------------------
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&wbemLocator);
if (FAILED(hr))
throw std::runtime_error("Failed to create IWbemLocator");
// Connect to the ROOT\\\microsoft\\windows\\storage
hr = wbemLocator->ConnectServer(
_bstr_t(L"ROOT\\cimv2\\storage"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (for example, Kerberos)
0, // Context object
&wbemServices); // pointer to IWbemServices proxy
if (FAILED(hr))
throw std::runtime_error("Could not connecct");
// Set security levels on the proxy -------------------------
hr = CoSetProxyBlanket(
wbemServices, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE); // proxy capabilities
if (FAILED(hr))
throw std::runtime_error("CoSetProxyBlanket()");
// do the work
EnumVolume(wbemServices);
ret = 0;
}
catch (const std::exception& ex) {
std::cout << "Exception: " << ex.what() << std::endl;
}
// is it safe>?
if (ret >= -1)
CoUninitialize();
return ret;
}
结论
通过遵循本文中的步骤,您可以解决 C++ WMI 枚举和获取实例方法失败的问题。请注意,代码仅作为示例,应根据具体情况进行调整。
常见问题解答
1. 为什么我会收到错误 HRESULT 0x8004101e?
- 此错误可能是由于以下原因之一造成的:使用了错误的根目录、无法获取方法接口、方法名或参数签名不正确、权限不足或防火墙设置阻止连接。
2. 如何验证 WMI 连接?
- 在连接到 WMI 时,使用正确的根目录路径:
ROOT\\cimv2\\storage
。
3. 如何检查方法可用性?
- 尝试使用
GetMethod
方法获取方法接口,如果失败,表明方法不可用。
4. 如何确保权限?
- 以具有适当权限(如管理员权限)的帐户运行代码。
5. 如何检查防火墙设置?
- 确保防火墙未阻止 WMI 连接。