I use the powershell script below to give the virtual machine a snapshot of the rct.
$vm1 = Get-WmiObject -ns root\Virtualization\v2 Msvm_ComputerSystem |?{$_.elementname -eq "backup_test4"}
$cms = Get-WmiObject -ns root\Virtualization\v2 Msvm_CollectionManagementService
$result = $cms.DefineCollection("rcttest", $null, 0)
$coll = [wmi]$result.DefinedCollection
$result = $cms.AddMember($vm1, $coll)
$csss = Get-WmiObject -ns root\Virtualization\v2 Msvm_CollectionSnapshotService
$result = $csss.CreateSnapshot([string]$coll, $null, 32768, $null)
It can generate snapshots normally. Therefore, I am going to refactor with C++. My code snippet is as follows:
HRESULT hresult = E_FAIL;
BSTR collectionClass = L"Msvm_CollectionManagementService";
IWbemClassObject* pInClass = NULL;
IWbemClassObject* pOutClass = NULL;
hresult = m_pWbemServices->GetObject(collectionClass,
0,
NULL,
&m_pWbemClassObject,
NULL);
if (FAILED(hresult)){
string msg = "Failed to get object.";
throw std::exception(msg.c_str());
}
// define collection
BSTR methodName1 = L"DefineCollection";
hresult = m_pWbemClassObject->GetMethod(
methodName1,
0,
&pInClass,
&pOutClass);
if (FAILED(hresult)){
string msg = "Failed to get method";
throw std::exception(msg.c_str());
}
According to the usage of DefineCollection()enter link description here, you need to set three three parameters for it, Collection name, GUID and Type. The code snippet is as follows:
//set param
VARIANT var;
BSTR paramName1 = L"Name";
var.vt = VT_BSTR;
var.bstrVal = _bstr_t(_collectionName.c_str());
hresult = pInClass->Put(paramName1,
0,
&var,
0);
if (FAILED(hresult)){
string msg = "Failed to set property.";
throw std::exception(msg.c_str());
}
BSTR paramName2 = L"Id";
var.vt = VT_BSTR;
var.bstrVal = _bstr_t("");
hresult = pInClass->Put(paramName2,
0,
&var,
0);
if (FAILED(hresult)){
string msg = "Failed to set property.";
throw std::exception(msg.c_str());
}
BSTR paramName3 = L"Type";
var.vt = VT_I2;
var.iVal = (uint16_t)0;
if (FAILED(hresult)){
string msg = "Failed to set property.";
throw std::exception(msg.c_str());
}
string SqlStr = "SELECT * FROM Msvm_CollectionManagementService";
cout << "sqlstr:" << SqlStr << endl;
IEnumWbemClassObject* pEnumerator = doExecQuery(SqlStr);
IWbemClassObject *pClassObj = NULL;
ULONG uReturn = 0;
while (1){
hresult = pEnumerator->Next(
WBEM_INFINITE,
1,
&pClassObj,
&uReturn);
if (FAILED(hresult)){
string msg = "Failed to get computer system.";
throw std::exception(msg.c_str());
}
break;
}
if (!pClassObj){
string msg = "The virtual machine was not found.";
throw std::exception(msg.c_str());
}
pClassObj->Get(L"__Path", 0, &var, 0, 0);
//invoke method
hresult = m_pWbemServices->ExecMethod(
var.bstrVal,
methodName1,
0,
NULL,
pInClass,
&pOutClass,
NULL);
if (FAILED(hresult)){
string msg = "Failed to invoke method.";
throw std::exception(msg.c_str());
}
According to the usage and script of AddMember()enter link description here, I need to add two parameters,Member and Collection. I did this.
VARIANT var;
BSTR paramName4 = L"Member";
//var.vt = VT_BYREF | VT_UNKNOWN;
//var.ppunkVal = (IUnknown**)m_pComputerSystem;
var.vt = VT_BYREF;
var.byref = (PVOID)m_pComputerSystem;
//var.vt = VT_UNKNOWN;
//var.punkVal = (IUnknown*)pInClass;
hresult = pInClass->Put(paramName4,
0,
&var,
0);
if (FAILED(hresult))
{
string msg = "Failed to set property.";
throw std::exception(msg.c_str());
}
BSTR paramName5 = L"Collection";
//var.vt = VT_BYREF | VT_UNKNOWN;
//var.ppunkVal = (IUnknown**)&collectionName;
//var.vt = VT_BYREF;
//var.byref = (PVOID)collectionName;
var.vt = VT_UNKNOWN;
var.punkVal = (IUnknown*)collectionName;
hresult = pInClass->Put(paramName5,
0,
&var,
0);
if (FAILED(hresult))
{
string msg = "Failed to set property.";
throw std::exception(msg.c_str());
}
string SqlStr = "SELECT * FROM Msvm_CollectionManagementService";
cout << "sqlstr:" << SqlStr << endl;
IEnumWbemClassObject* pEnumerator = doExecQuery(SqlStr);
IWbemClassObject *pClassObj = NULL;
ULONG uReturn = 0;
while (1)
{
hresult = pEnumerator->Next(
WBEM_INFINITE,
1,
&pClassObj,
&uReturn);
if (FAILED(hresult))
{
string msg = "Failed to get computer system.";
throw std::exception(msg.c_str());
}
break;
}
if (!pClassObj)
{
string msg = "The virtual machine was not found.";
throw std::exception(msg.c_str());
}
pClassObj->Get(L"__Path", 0, &var, 0, 0);
//invoke method
hresult = m_pWbemServices->ExecMethod(
var.bstrVal,
methodName2,
0,
NULL,
pInClass,
&pOutClass,
NULL);
if (FAILED(hresult))
{
string msg = "Failed to invoke method.";
throw std::exception(msg.c_str());
}
The return value of each execution of ExecMethod() is 2147749935 (0x8004102F). According to MSDN's description of the AddMember() parameter, I didn't really understand what Member and Collection are. I passed those two parameters. It should be really wrong, but I can't find it. Please give me some guidance, thank you
User contributions licensed under CC BY-SA 3.0