I am attempting to use SoftwareLicensingService::InstallProductKey to install a product key on Windows 7 through WMI/C++ in a Service. However every time I attempt to call the method via IWbemServices::ExecMethod I get 0x8004102f which is WBEM_E_INVALID_METHOD_PARAMETERS. I thought this was something to do with the product key I am passing, but I have since then tried similar code for Win32_WindowsProductActivation::ActivateOnline [which is a no parameter method available on XP] with the same error. Does anyone know what is suspect in my code fragment below (I have skipped some cleanup code to be brief) ? The same sequence of code successfully invokes other WMI methods however.
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;
}
I have since figured what the issue was. The method call was being made on the class not the instance.
This code will work properly:
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 );
This code is not only for this class and method.Generally for any class you can get the objectPath(1st parameter of ExecMethod()) and use it.This code mentioned is for Calling a method without parameters.
The code for method calling with parameters is available here.In some cases, calling ExecMethod with input parameters for a method returns WBEM_E_INVALID_METHOD_PARAMETERS error. In that case you can get the object path first and then call GetObejct and GetMethod functions.
User contributions licensed under CC BY-SA 3.0