来自 ExecMethod 的错误 WBEM_E_INVALID_METHOD_PARAMETERS

Posted

技术标签:

【中文标题】来自 ExecMethod 的错误 WBEM_E_INVALID_METHOD_PARAMETERS【英文标题】:Error WBEM_E_INVALID_METHOD_PARAMETERS from ExecMethod 【发布时间】:2015-05-13 17:42:48 【问题描述】:

我正在尝试使用 SoftwareLicensingService::InstallProductKey 通过服务中的 WMI/C++ 在 Windows 7 上安装产品密钥。但是,每次我尝试通过 IWbemServices::ExecMethod 调用该方法时,我都会得到 0x8004102f,即 WBEM_E_INVALID_METHOD_PARAMETERS。我认为这与我传递的产品密钥有关,但此后我为 Win32_WindowsProductActivation::ActivateOnline [这是 XP 上可用的无参数方法] 尝试了类似的代码,但出现相同的错误.有谁知道下面我的代码片段中有什么可疑之处(为了简短起见,我跳过了一些清理代码)?然而,相同的代码序列成功地调用了其他 WMI 方法。

int _tmain(int argc, _TCHAR* argv[])

    HRESULT hr = S_OK;
    IWbemLocator *pLoc = NULL;
    IWbemServices *pServices = NULL;
    IWbemClassObject *pInputParamsClass = NULL;
    IWbemClassObject *pInputParams = NULL;
    IWbemClassObject *pOutputParams = NULL;
    IWbemClassObject *pLicensingClsObj = NULL;
    VARIANT vtProductKey = 0;
    VARIANT vtPath = 0;


    hr =  CoInitializeEx(0, COINIT_MULTITHREADED);
    if(FAILED(hr))
        goto cleanup;

hr =  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, 
            RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
_ASSERT(SUCCEEDED(hr));
if(FAILED(hr))
    goto cleanup;

hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, 
            IID_IWbemLocator, (LPVOID *)&pLoc);
_ASSERT(SUCCEEDED(hr) && (NULL != pLoc));
if(FAILED(hr) || (NULL == pLoc))
    goto cleanup;

hr = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 
            0, 0, &pServices);
_ASSERT(SUCCEEDED(hr) && (NULL != pServices));
if(FAILED(hr) || (NULL == pServices))
    goto cleanup;

hr = CoSetProxyBlanket(pServices, RPC_C_AUTHN_WINNT, 
   RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE,
   NULL, EOAC_NONE);
_ASSERT(SUCCEEDED(hr));
if(FAILED(hr))
    goto cleanup;

hr = pServices->GetObject(_bstr_t(L"SoftwareLicensingService"), 
                        0, NULL, &pLicensingClsObj, NULL);
_ASSERT(SUCCEEDED(hr) && (NULL != pLicensingClsObj));
if(FAILED(hr) || (NULL == pLicensingClsObj))
    goto cleanup;

hr = pLicensingClsObj->Get(L"__Path", 0, &vtPath, 0, 0);
_ASSERT(SUCCEEDED(hr));
if(FAILED(hr))
    goto cleanup;

hr = pLicensingClsObj->GetMethod(L"InstallProductKey", 0, 
            &pInputParamsClass, NULL);
_ASSERT(SUCCEEDED(hr) && (NULL != pInputParamsClass));
if(FAILED(hr) || (NULL == pInputParamsClass))
    goto cleanup;

hr = pInputParamsClass->SpawnInstance(0, &pInputParams);
_ASSERT(SUCCEEDED(hr) && (NULL != pInputParams));
if(FAILED(hr) || (NULL == pInputParams))
    goto cleanup;

vtProductKey.vt = VT_BSTR;
vtProductKey.bstrVal = SysAllocString(L"XXXXXXXXXXXXXXXXXXXXXXXXX");
hr = pInputParams->Put(L"ProductKey", 0, &vtProductKey, 0);
_ASSERT(SUCCEEDED(hr));
if(FAILED(hr))
    goto cleanup;

hr = pServices->ExecMethod(vtPath.bstrVal, 
            _bstr_t(L"InstallProductKey"), 
            0, NULL, pInputParams, 
            &pOutputParams, NULL);
_ASSERT(SUCCEEDED(hr) && (NULL != pOutputParams));
if(FAILED(hr) || (NULL == pOutputParams))
    goto cleanup;

hr = S_OK;//all success

cleanup:
if(NULL != pLoc)

    pLoc->Release();
    pLoc = NULL;

if(NULL != pServices)

    pServices->Release();
    pServices = NULL;

(VOID)CoUninitialize();
return hr;

【问题讨论】:

"ROOT\CIMV2" 必须是 "ROOT\\CIMV2"。您对任何 COM 调用的错误检查在哪里?你如何填充vtProductKey?请提供MCVE。 @Remy - 这是一个错字。假设这是带错误检查的工作代码并成功调用其他 wmi 方法。我会修复有问题的字符串。 请不要让人假设。请提供“实际”代码,而不是“简化”代码。 @Remy 道歉,发布实际代码将违反公司政策。谢谢。 因此需要一个能够重现相同问题的 MCVE。但是,除了 vtProductKey 的值之外,此代码示例中没有任何内容是专有的。 【参考方案1】:

我已经知道问题出在哪里了。方法调用是在类而不是实例上进行的。

【讨论】:

我猜也有同样的问题。我不明白这意味着“方法调用是在类而不是实例上进行的”。您能说出要更改您发布的原始代码以使其正常工作吗?【参考方案2】:

此代码将正常工作:

 IEnumWbemClassObject * enum_obj;
    hres = pSvc>CreateInstanceEnum(_bstr_t(L"SoftwareLicensingService"),WBEM_FLAG_RETURN_IMMEDIATELY , NULL ,&enum_obj);


   IWbemClassObject * spInstance;
   ULONG uNumOfInstances = 0;
   hres = enum_obj->Next(10000, 1,&spInstance,&uNumOfInstances);

   VARIANT path;
   hres = spInstance->Get(_bstr_t("__Path"), 0,&path, 0, 0);

   IWbemClassObject *results = NULL;
   hres = pSvc->ExecMethod( path.bstrVal, _bstr_t( L"InstallProductKey" ), 0,
   NULL,NULL,&results, NULL );

此代码不仅适用于此类和方法。通常对于任何类,您都可以获得objectPath(ExecMethod()的第一个参数)并使用它。提到的此代码用于调用不带参数的方法。

带参数的方法调用代码在here可用。在某些情况下,为方法调用带输入参数的ExecMethod会返回WBEM_E_INVALID_METHOD_PARAMETERS错误。在这种情况下,您可以先获取对象路径,然后调用 GetObejct 和 GetMethod 函数。

【讨论】:

以上是关于来自 ExecMethod 的错误 WBEM_E_INVALID_METHOD_PARAMETERS的主要内容,如果未能解决你的问题,请参考以下文章

__init__.py 是 python 的后裔,但不是来自 c++;导致“导入 matplotlib”错误

MSVC 中的链接错误 LNK2019,带有 __imp__ 前缀的未解析符号,但应该来自静态库

来自 Flask-MongoKit 的元类错误

获取 nafxcwd.lib(timecore.obj) 错误 lnk2001 无法解析的外部符号 __mbctype 在来自其他项目的标头包含之后

来自 PREfast 的指针无效访问(读取 0*1 的 4 个字节)错误

来自 vue js 的 3 个函数错误