简体   繁体   English

在C ++中从WMI中的OUT参数获取值

[英]Getting value from an OUT parameter in WMI in C++

I am trying to read a registry value using WMI. 我正在尝试使用WMI读取注册表值。 Here is what I have now: 这是我现在所拥有的:

    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;

For some reason I never get a correct varReturnValue. 出于某种原因,我从未获得正确的varReturnValue。 Here is the function: http://msdn.microsoft.com/en-us/library/aa390788(v=vs.85).aspx 这是功能: http : //msdn.microsoft.com/zh-cn/library/aa390788(v=vs.85).aspx

Been a while but... have you called VariantInit on the Variant first. 已经有一段时间了,但是...您是否先在Variant上调用了VariantInit。 IIRC it needs to be initialised when calling COM methods. IIRC它需要在调用COM方法时进行初始化。

Here is an example that will answer your question. 这是一个可以回答您问题的示例。 In the example, I find out the name of the current document being printed. 在示例中,我找出了要打印的当前文档的名称。

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;

You put in "sSubKeyName" and "sValueName" the same value - &sSubKeyName. 您在“ 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

I think you meant to do this: 我认为您打算这样做:

// 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM