HRESULT hr;
IWbemClassObject *pInClass = NULL;
IWbemClassObject *pOutClass = NULL;

IWbemContext     *pCtx = 0;
IWbemCallResult  *pResult = 0;
BSTR snapshotClassPath = SysAllocString(L"Msvm_VirtualSystemSnapshotService");
hr = m_pWbemServices->GetObject(
    snapshotClassPath,
    0,
    NULL,
    &m_pWbemClassObject,
    NULL);
if (FAILED(hr))
{
    std::cout << "Failed to get class object(Msvm_VirtualSystemSnapshotService). Error code = 0x" << hex << hr << std::endl;
    return;
}

// Create snapshot method
BSTR MethodNameOne = SysAllocString(L"CreateSnapshot");

hr = m_pWbemClassObject->GetMethod(
    MethodNameOne,
    0,
    &pInClass,
    &pOutClass
);
if (FAILED(hr))
{
    std::cout << "Failed to get method(CreateSnapshot). Error code = 0x" << hex << hr << endl;
}
cout << "Succeeded to get method(CreateSnapshot)." << endl;


BSTR virtualSystemSnaphotSettingData = SysAllocString(L"Msvm_VirtualSystemSnapshotSettingData");
// Get the Msvm_VirtualSystemSnapshotSettingData Class object
IWbemClassObject * pvirtualSystemSnaphotSettingData = NULL;

hr = m_pWbemServices->GetObject(
    virtualSystemSnaphotSettingData,
    0,
    pCtx,
    &pvirtualSystemSnaphotSettingData,
    &pResult
);
if (FAILED(hr))
{
    wprintf(L"Error GetObject Msvm_VirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
std::cout << "Succeeded to get object(Msvm_VirtualSystemSnapshotSettingData)." << std::endl;

// Create instance of Msvm_VirtualSystemSnapshotSettingData class
IWbemClassObject * pInpInstOfSnapshotSettingData = NULL;
hr = pvirtualSystemSnaphotSettingData->SpawnInstance(
    0,
    &pInpInstOfSnapshotSettingData);
if (FAILED(hr))
{
    wprintf(L"Error SpawnInstance Msvm_VirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
std::cout << "Succeeded to created instance(Msvm_VirtualSystemSnapshotSettingData )." << std::endl;

// Set the property(Consistency Level)
BSTR memberOneForVirtualSystemSnapshotSettingData = SysAllocString(L"ConsistencyLevel");
VARIANT consistencyLevel;
VariantInit(&consistencyLevel);
V_VT(&consistencyLevel) = VT_BSTR;
V_BSTR(&consistencyLevel) = SysAllocString(L"1");
hr = pInpInstOfSnapshotSettingData->Put(
    memberOneForVirtualSystemSnapshotSettingData,
    0,
    &consistencyLevel,
    0);
if (FAILED(hr))
{
    wprintf(L"Error memberOneForVirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(ConsistencyLevel), Consistency level:%s\n", consistencyLevel.bstrVal);
VariantClear(&consistencyLevel);

Windows Hyper-V 2016上调用了CreateSnapshot方法,执行成功,但是生成的虚拟机快照在Hyper-V GUI中不可见。

//设置属性(ElementName)
BSTR memberThreeForVirtualSystemSnapshotSettingData = SysAllocString(L“ElementName”);
变量elementName;
VariantInit(&elementName);
V_VT(&elementName)= VT_BSTR;
V_BSTR(&elementName)= SysAllocString(vmName);
hr = pInpInstOfSnapshotSettingData->Put(
    memberThreeForVirtualSystemSnapshotSettingData,
    0,
    &elementName,
    0);
if (FAILED(hr))
{
    wprintf(L"Failed to set property(ElementName), Erorr code:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(ElementName):%s\n", elementName.bstrVal);
VariantClear(&elementName);

// Set the property(ignore disks that aren't compatible with snapshots)
BSTR memberTwoForVirtualSystemSnapshotSettingData = SysAllocString(L"IgnoreNonSnapshottableDisks");
VARIANT ignoreNonSnapshottableDisks;
ignoreNonSnapshottableDisks.vt = VT_BOOL;
ignoreNonSnapshottableDisks.boolVal = true;

hr = pInpInstOfSnapshotSettingData->Put(
    memberTwoForVirtualSystemSnapshotSettingData,
    0,
    &ignoreNonSnapshottableDisks,
    0);
if (FAILED(hr))
{
    wprintf(L"Error memberTwoForVirtualSystemSnapshotSettingData:0x%08lx\n", hr);
}
wprintf(L"Succeeded to set property(IgnoreNonSnapshottableDisks):%d\n", ignoreNonSnapshottableDisks.boolVal);
VariantClear(&ignoreNonSnapshottableDisks);

// Create or update instance
hr = m_pWbemServices->PutInstance(
    pInpInstOfSnapshotSettingData,
    0,
    pCtx,
    &pResult);
if (FAILED(hr))
{
    wprintf(L"Error PutInstance:0x%08lx\n", hr);
}
wprintf(L"Succeeded to update the instance.\n");

// Get textual rendering of the object in the MOF syntax
BSTR objString = NULL;
hr = pInpInstOfSnapshotSettingData->GetObjectText(0, &objString);
if (FAILED(hr))
{
    wprintf(L"Error GetObjectText:0x%08lx\n", hr);
}
wprintf(L"Succeeded to get textual rendering.\n");

BSTR ArgNameTwo = SysAllocString(L"SnapshotSettings");
VARIANT v;
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = objString;
wprintf(L"Object text: %s\n", objString);

// Pass the second Argument to CreateSnapshot method
hr = pInClass->Put(ArgNameTwo, 0, &v, 0);
if (FAILED(hr))
{
    wprintf(L"Error ArgNameTwo:0x%08lx\n", hr);
}
VariantClear(&v);
wprintf(L"Succeeded to set property(SnapshotSettings).\n");

// set property(AffectedSystem)
VARIANT vtProp;
m_pWbemClassObject->Get(L"__Path", 0, &vtProp, 0, 0);
hr = pInClass->Put(L"AffectedSystem", 0, &vtProp, NULL);
if (FAILED(hr))
{
    std::cout << "Failed to set property(AffectedSystem)." << std::endl;
}
wprintf(L"AffectedSystem: %s\n", vtProp.bstrVal);
VariantClear(&vtProp);

// Pass the Third Argument to CreateSnapshot method
BSTR ArgNameThree = SysAllocString(L"SnapshotType");
VARIANT var;
VariantInit(&var);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(L"32768");
hr = pInClass->Put(ArgNameThree, 0, &var, 0);
if (FAILED(hr))
{
    std::cout << "Failed to set property(SnapshotType)." << std::endl;
}
wprintf(L"SnapshotType: %s\n", var.bstrVal);
VariantClear(&var);

// Call the CreateSnapshot method.
IEnumWbemClassObject* pEnumOb1 = NULL;
hr = m_pWbemServices->ExecQuery(
    BSTR(L"WQL"),
    BSTR(L"SELECT * FROM Msvm_VirtualSystemSnapshotService"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumOb1
);
if (FAILED(hr)) {
    std::cout << "SELECT * FROM Msvm_VirtualSystemSnapshotService, Error code:0x%08lx" << hex << hr << endl;
}
std::cout << "Succeeded to query snapshot." << std::endl;

IWbemClassObject *pclsObj1 = NULL;
ULONG uReturn1 = 0;

std::cout << "Create snapshot..." << std::endl;
while (1)
{
    HRESULT hr = pEnumOb1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn1);

    if (FAILED(hr) || !uReturn1)
    {
        break;
    }
    VARIANT vt;
    // Get the value of the path property from Msvm_VirtualSystemSnapshotService Class
    hr = pclsObj1->Get(L"__Path", 0, &vt, 0, 0);
    if (FAILED(hr))
    {
        std::wcout << "Failed to get vm's path." << std::endl;
        break;
    }
    wprintf(L"__PATH:%s \n", vt.bstrVal);

    //Call the CreateSnapshot method
    hr = m_pWbemServices->ExecMethod(
        vt.bstrVal,
        MethodNameOne,
        0,
        NULL,
        pInClass,
        &pOutClass,
        NULL);
    if (FAILED(hr))
    {
        wprintf(L"Failed to execute(CreateSnapshot), Erorr code:0x%08lx\n", hr);
        break;
    }
    wprintf(L"Succeeded to create snapshot.\n");
    Sleep(10);

    pclsObj1->Release();
    pclsObj1 = NULL;
}

ExecMethod()的返回值为0,即调用成功,但是我没有看到仅在Hyper-V上创建的快照。

最佳答案

我使用此PowerShell脚本,它可以工作。唯一的问题是设置快照名称:

function Create-VMSnapshot{
    $vm = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Query "select * from msvm_computersystem where elementname='$VMName'"
    if($vm -eq $null){
        throw "Failed to get VM with display name '$VMName'"
    }

    $Msvm_VirtualSystemSnapshotService = Get-WmiObject -Namespace $Namespace -ComputerName $ComputerName -Class Msvm_VirtualSystemSnapshotService
    if($Msvm_VirtualSystemSnapshotService -eq $null)
    {
        throw "Failed to get Msvm_VirtualSystemSnapshotService instance"
    }
    [WMI]$Msvm_VirtualSystemSnapshotSettingData = ([WMIClass]"\\.\root\virtualization\v2:Msvm_VirtualSystemSnapshotSettingData").CreateInstance()
    if($Msvm_VirtualSystemSnapshotSettingData -eq $null)
    {
        throw "Failed to get Msvm_VirtualSystemSnapshotSettingData instance"
    }
    $Msvm_VirtualSystemSnapshotSettingData.ConsistencyLevel = 1
    $Msvm_VirtualSystemSnapshotSettingData.IgnoreNonSnapshottableDisks = $true
    $Msvm_VirtualSystemSnapshotSettingData.ElementName = $SnapshotName
    $Msvm_VirtualSystemSnapshotSettingData.Description = $SnapshotDescription
    $Msvm_VirtualSystemSnapshotSettingData

    [System.Management.ManagementBaseObject]$result = $Msvm_VirtualSystemSnapshotService.CreateSnapshot(
        $vm,
        $Msvm_VirtualSystemSnapshotSettingData.GetText(2),
        32768)
    [int]$res = Job-Observation -WMIJobResult $result -JobAction "Creating snapshot" -JobProgressCaption "Create snapshot"
    $snapshot = (([WMI]$result.Job).GetRelated("Msvm_VirtualSystemSettingData") | % {$_})
    $snapshot
}

关于c++ - CreateSnapshot()是否不会生成Hyper-V虚拟机快照?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53589849/

10-09 05:59