Как исправить ошибку, которая вызывает AddMember () для возврата «WBEM_E_INVALID_METHOD_PARAMETERS»? - PullRequest
0 голосов
/ 17 апреля 2019

Я использую приведенный ниже скрипт powershell, чтобы дать виртуальной машине моментальный снимок 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)

Он может генерировать снимки в обычном режиме.Поэтому я собираюсь провести рефакторинг с C ++.Мой фрагмент кода выглядит следующим образом:

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());
}

В соответствии с использованием DefineCollection () введите здесь описание ссылки , вам нужно установить для него три параметра: Имя коллекции, GUID иТип.Фрагмент кода выглядит следующим образом:

//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());
}

В соответствии с использованием и сценарием AddMember () введите здесь описание ссылки , мне нужно добавить два параметра, Member и Collection.Я сделал это.

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());
}

Возвращаемое значение каждого выполнения ExecMethod () - 2147749935 (0x8004102F).Согласно описанию MSDN параметра AddMember (), я не совсем понял, что такое Member и Collection.Я передал эти два параметра.Это должно быть действительно неправильно, но я не могу найти это.Пожалуйста, дайте мне некоторое руководство, спасибо

...