【问题标题】:Getting value from an OUT parameter in WMI in C++从 C++ 中 WMI 中的 OUT 参数获取值
【发布时间】: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

【问题讨论】:

    标签: c++ windows wmi


    【解决方案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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-26
          • 1970-01-01
          • 1970-01-01
          • 2011-09-19
          • 1970-01-01
          • 2021-11-29
          • 2023-04-09
          • 2012-11-11
          相关资源
          最近更新 更多