从 C++ 中 WMI 中的 OUT 参数获取值
Posted
技术标签:
【中文标题】从 C++ 中 WMI 中的 OUT 参数获取值【英文标题】:Getting value from an OUT parameter in WMI in C++ 【发布时间】:2014-02-10 13:11:23 【问题描述】:我正在尝试使用 WMI 读取注册表值。这是我现在拥有的:
BSTR methodName = SysAllocString(L"GetStringValue");
BSTR className = SysAllocString(L"StdRegProv");
IWbemClassObject* pInParamsDefinition = nullptr;
std::wstring errStr = L"ERROR";
HRESULT hRes = p_regWbemClassObj->GetMethod(methodName, 0, &pInParamsDefinition, NULL);
IWbemClassObject* pClassInstance = NULL;
hRes = pInParamsDefinition->SpawnInstance(0, &pClassInstance);
// Create the values for the in parameters
VARIANT sSubKeyName;
sSubKeyName.vt = VT_BSTR;
sSubKeyName.bstrVal = BSTR(path.c_str());
VARIANT sValueName;
sValueName.vt = VT_BSTR;
sValueName.bstrVal = BSTR(key.c_str());
// Store the value for the in parameters
hRes = pClassInstance->Put(L"sSubKeyName", 0,
&sSubKeyName, 0);
hRes = pClassInstance->Put(L"sValueName", 0,
&sSubKeyName, 0);
// Execute Method
IWbemClassObject* pOutParams = NULL;
hRes = p_defWbemServices->ExecMethod(className, methodName, 0,
NULL, pClassInstance, &pOutParams, NULL);
if (FAILED(hRes))
VariantClear(&sSubKeyName);
VariantClear(&sValueName);
SysFreeString(className);
SysFreeString(methodName);
pInParamsDefinition->Release();
pClassInstance->Release();
pOutParams->Release();
return errStr;
VARIANT varReturnValue;
hRes = pOutParams->Get(BSTR(L"sValue"), 0, &varReturnValue, NULL, NULL);
std::wstring result = varReturnValue.bstrVal;
由于某种原因,我从未得到正确的 varReturnValue。 这是函数:http://msdn.microsoft.com/en-us/library/aa390788(v=vs.85).aspx
【问题讨论】:
【参考方案1】:已经有一段时间了,但是...您是否首先在 Variant 上调用了 VariantInit。 IIRC 在调用 COM 方法时需要初始化。
【讨论】:
【参考方案2】:这是一个可以回答您问题的示例。在示例中,我找出了当前正在打印的文档的名称。
using std::cout;
using std::cin;
using std::endl;
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hRes))
cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
return 1;
if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
return 1;
IWbemLocator* pLocator = NULL;
if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
return 1;
IWbemServices* pService = NULL;
if (FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
pLocator->Release();
cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
return 1;
IEnumWbemClassObject* pEnumerator = NULL;
if (FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT Documents FROM Win32_PrintJob", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
pLocator->Release();
pService->Release();
cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;
return 1;
IWbemClassObject* clsObj = NULL;
int numElems;
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
if (FAILED(hRes))
break;
VARIANT vRet;
VariantInit(&vRet);
if (SUCCEEDED(clsObj->Get(L"Description", 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR)
std::wcout << L"Description: " << vRet.bstrVal << endl;
VariantClear(&vRet);
clsObj->Release();
pEnumerator->Release();
pService->Release();
pLocator->Release();
return 0;
【讨论】:
【参考方案3】:您在“sSubKeyName”和“sValueName”中输入了相同的值 - &sSubKeyName。
// Store the value for the in parameters
hRes = pClassInstance->Put(L"sSubKeyName", 0,
&sSubKeyName, 0); // <-- sSubKeyName
hRes = pClassInstance->Put(L"sValueName", 0,
&sSubKeyName, 0); // <-- sSubKeyName
我认为你的本意是:
// Store the value for the in parameters
hRes = pClassInstance->Put(L"sSubKeyName", 0,
&sSubKeyName, 0); // <-- sSubKeyName
hRes = pClassInstance->Put(L"sValueName", 0,
&sValueName, 0); // <-- sValueName
【讨论】:
以上是关于从 C++ 中 WMI 中的 OUT 参数获取值的主要内容,如果未能解决你的问题,请参考以下文章