(WMI)ExecMethod输出参数 - 无论调用结果如何,ResultingSnapshot都为NULL,为什么?

时间:2018-04-11 13:13:39

标签: c++ wmi

我正在使用WMI创建RCT检查点。以下是代码段。问题是,当我使用Create Snapshot调用方法ExecMethod时,会创建检查点,但ResultingSnapshot仍然指向NULL

由于调用是异步的(因为pOutParameters的返回值是4096),我还等到WaitForJobCompletion中的作业完成但pOutParameters未更新仍然是ResultingSnapshot为NULL。

基本上,我需要这个ResultingSnapshot来创建参考点。如果还有其他方法可以做,我可以写,但需要指导。

我是WMI的新手,感谢任何帮助或领导。

HRESULT hr;
CComPtr<IWbemClassObject> pInParams;
CComPtr<IWbemClassObject> pOutParameters;
IWbemCallResult *pResult = 0;

// Set Method Paramters
this->GetMethodParams(L"Msvm_VirtualSystemSnapshotService", L"CreateSnapshot", &pInParams);

IWbemClassObject * pVirtualSystemSnaphotSettingData = NULL;
hr = m_pWbemServices->GetObject(L"Msvm_VirtualSystemSnapshotSettingData", 0, NULL, &pVirtualSystemSnaphotSettingData, &pResult);

IWbemClassObject * pInpInstOfSnapshotSettingData = NULL;
hr = pVirtualSystemSnaphotSettingData->SpawnInstance(0, &pInpInstOfSnapshotSettingData);

VARIANT consistencyLevel;
VariantInit(&consistencyLevel);
V_VT(&consistencyLevel) = VT_BSTR;
V_BSTR(&consistencyLevel) = SysAllocString(L"1");
hr = pInpInstOfSnapshotSettingData->Put(L"ConsistencyLevel", 0, &consistencyLevel, 0);
VariantClear(&consistencyLevel);

VARIANT elementName;
VariantInit(&elementName);
V_VT(&elementName) = VT_BSTR;
V_BSTR(&elementName) = SysAllocString(L"rhel-1");
hr = pInpInstOfSnapshotSettingData->Put(L"ElementName", 0, &elementName, 0);
VariantClear(&elementName);

hr = m_pWbemServices->PutInstance(pInpInstOfSnapshotSettingData, 0, NULL, &pResult);

BSTR objString = NULL;
hr = pInpInstOfSnapshotSettingData->GetObjectText(0, &objString);
BSTR ArgNameTwo = SysAllocString(L"SnapshotSettings");
VARIANT v;
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = objString; 

hr = pInParams->Put(ArgNameTwo, 0, &v, 0);

VARIANT vtProp;
m_pVmWbemClassObject->Get(L"__Path", 0, &vtProp, 0, 0);

wprintf(L"Affected System : : %ls", (LPWSTR)vtProp.bstrVal);
HRESULT hres = pInParams->Put(L"AffectedSystem", 0 , &vtProp, NULL);

VARIANT var;
VariantInit(&var);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(L"2");


CHK_HRES(pInParams->Put(L"SnapshotType", 0, &var, 0));


IEnumWbemClassObject* pEnumOb = NULL;
hr = m_pWbemServices->ExecQuery(
BSTR(L"WQL"),
BSTR(L"select * from Msvm_VirtualSystemSnapshotService"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumOb);
IWbemClassObject *pclsObj1 = NULL;
ULONG uReturn1 = 0;

while (1)
{
    HRESULT hr = pEnumOb->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn1);

    if (0 == uReturn1)
    {
        break;
    }

    IWbemCallResult *pCallResult = NULL;
    IWbemClassObject *pResObj = NULL;

    CComBSTR path(this->GetStrProperty(L"__PATH", pclsObj1));

    hr = m_pWbemServices->ExecMethod(path, L"CreateSnapshot", 0, NULL, pInParams, &pOutParameters, &pCallResult);



    /* cout << "check1 : " << hex << hr << endl;
    hr = pCallResult->GetResultObject(0, &pResObj);
    cout << "check2" << endl;*/

    this->WaitForJobCompletion(pOutParameters);
   }

cout << "\nSnpshot Complete" << endl;
}

修改 我发现SnapshotType参数设置不正确它应该是32768我已经使用以下方式将uint16转换为Variant但没有成功,我得到0x80070057 Incorrect Parameter错误。

VARIANT var;
VariantInit(&var);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(L"32768");

hr = pInParams->Put(L"SnapshotType", 0, &var, CIM_UINT16);

3 个答案:

答案 0 :(得分:3)

HRESULT GetRelated(PWSTR sAssociatePath, PWSTR sResultClass, IWbemClassObject** ppResultObject)
{
CStringW query;
query.Format(L"associators of {%s} where ResultClass = %s", sAssociatePath, sResultClass);

CComPtr<IEnumWbemClassObject> pEnumOb;

HRESULT hr = m_pWbemServices->ExecQuery(
    BSTR(L"WQL"),
    CComBSTR(query),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumOb));
ULONG uReturn = 0;
CComPtr<IWbemClassObject> pObject;
hr = pEnumOb->Next(WBEM_INFINITE, 1, &pObject, &uReturn);
return hr;
}
// Call the GetRelated function above with the __PATH parameter of JOB
CComPtr<IWbemClassObject> pOutParam = NULL;
CHK_HRES(this->ExecMethod(pHyperVObject, L"ConvertToReferencePoint", pInParams, &pOutParam, NULL));
CComVariant jobPath;
CHK_HRES(pOutParam->Get(L"Job", 0, &jobPath, NULL, NULL));
CComPtr<IWbemClassObject> pResult;
GetRelated(jobPath.bstrVal, L"Msvm_VirtualSystemReferencePoint", &pResult);

答案 1 :(得分:0)

您提供ppCallResult参数。来自documentation

  

ppCallResult [out]如果为NULL,则不使用它。如果ppCallResult是   指定时,必须将其设置为在入口时指向NULL。 在这种情况下,   使用WBEM_S_NO_ERROR立即调用返回。 ppCallResult   参数接收指向新的IWbemCallResult对象的指针,   必须轮询以获取方法执行的结果使用   GetCallStatus 方法。呼叫的输出参数可用   调用IWbemCallResult :: GetResultObject。

因此,您需要在GetCallStatus上使用pCallResult,直到方法完成,然后GetResultObject才能获得输出参数:

LONG status;
while ((hr = pCallResult->GetCallStatus(1000, &status)) == WBEM_S_TIMEDOUT);
/* check hr and status here */
hr = pCallResult->GetResultObject(0, &pResObj);

或使用WBEM_INFINITE:

LONG status;
hr = pCallResult->GetCallStatus(WBEM_INFINITE, &status);
/* check hr and status here */
hr = pCallResult->GetResultObject(0, &pResObj);

或者提供NULL代替pCallResult,它将是同步调用,其中pOutParameters将被设置:

hr = m_pWbemServices->ExecMethod(path, L"CreateSnapshot", 0, NULL, pInParams, &pOutParameters, NULL);

答案 2 :(得分:0)

SnapshotType = 32768是否给您带来错误? 因为使用此快照类型时不会创建快照。

正在创建以下日志:

“ Ubuntu1”的检查点创建失败,因为指定了无效的检查点类型。 (虚拟机ID 5C773BB5-B630-48B4-AB9E-71C548F3FAE4)

编辑:我不确定是否有帮助,但这解决了我的问题: https://docs.microsoft.com/en-us/answers/questions/160321/wmi-createsnapshot-not-working-with-snapshottype-3.html