(WMI) ExecMethod 输出参数 - 无论调用结果如何,ResultingSnapshot 都是 NULL,为什么?
(WMI) ExecMethod out parameter - ResultingSnapshot is NULL irrespective of the result of the call, Why?
我正在使用 WMI 创建 RCT 检查点。下面是代码片段。问题是当我使用 ExecMethod
调用方法 Create Snapshot
时,检查点被创建但是 ResultingSnapshot
仍然指向 NULL
.
由于调用是异步的(因为 pOutParameters
的 return 值为 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);
您提供了一个 ppCallResult
参数。来自 documentation:
ppCallResult [out] If NULL, this is not used. If ppCallResult is
specified, it must be set to point to NULL on entry. In this case, the
call returns immediately with WBEM_S_NO_ERROR. The ppCallResult
parameter receives a pointer to a new IWbemCallResult object, which
must be polled to obtain the result of the method execution using the
GetCallStatus method. The out parameters for the call are available by
calling IWbemCallResult::GetResultObject.
因此您需要在 pCallResult
上使用 GetCallStatus
直到方法完成,然后 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);
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);
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
我正在使用 WMI 创建 RCT 检查点。下面是代码片段。问题是当我使用 ExecMethod
调用方法 Create Snapshot
时,检查点被创建但是 ResultingSnapshot
仍然指向 NULL
.
由于调用是异步的(因为 pOutParameters
的 return 值为 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);
您提供了一个 ppCallResult
参数。来自 documentation:
ppCallResult [out] If NULL, this is not used. If ppCallResult is specified, it must be set to point to NULL on entry. In this case, the call returns immediately with WBEM_S_NO_ERROR. The ppCallResult parameter receives a pointer to a new IWbemCallResult object, which must be polled to obtain the result of the method execution using the GetCallStatus method. The out parameters for the call are available by calling IWbemCallResult::GetResultObject.
因此您需要在 pCallResult
上使用 GetCallStatus
直到方法完成,然后 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);
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);
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