2016-05-12 116 views
1

我发现了一些使用C#和VBS进行WMI实例删除的示例,但是我需要使用C++实现此示例。使用C++删除WMI实例

我的示例代码:

CoInitialize(NULL); 

HRESULT hRes; 

//Obtain the initial locator to WMI 
CComPtr<IWbemLocator> pLoc = NULL; 
hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*) &pLoc); 
if(FAILED(hRes)) 
    return 1; 

//Connect to WMI through the IWbemLocator::ConnectServer method 
CComPtr<IWbemServices> pSvc = NULL; 
//Connect to the root namespace with the current user and obtain pointer pSvc to make IWbemServices calls. 
hRes = pLoc->ConnectServer(L"ROOT\\SUBSCRIPTION", NULL, NULL, 0, NULL, 0, 0, &pSvc); 
if(FAILED(hRes)) 
    return 1; 

hRes = pSvc->DeleteInstance(
      L"CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}'", 
      WBEM_FLAG_RETURN_IMMEDIATELY, NULL, NULL); 

return 0; 

据我发现herehere,我的代码应该工作。我肯定会CommandLineEventConsumer命名为{709782F3-E860-488E-BD8A-89FBC8C1495C}

我的代码失败在IWbemServices::DeleteInstance,错误代码0x80041008(其中一个参数来调用的是不正确的)。

如果有人在我的代码中发现错误,我将不胜感激。或者可能需要一些特权才能做到这一点?

回答

0

我发现两种解决方案:

1.去除WBEM_FLAG_RETURN_IMMEDIATELY标志。

_bstr_t objPath(L"CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}'"); 
hRes = pSvc->DeleteInstance(objPath, 0, NULL, NULL); 

2.通过IWbemCallResult查询结果。

_bstr_t objPath(L"CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}'"); 
CComPtr<IWbemCallResult> pRes = NULL; 
hRes = pSvc->DeleteInstance(objPath, WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pRes); 

没有调查很多,但它有效的两种方式。看起来像规格不是100%正确的。

2

IWbemServices::DeleteInstance的第一个参数是BSTR。 A BSTR与UTF-16编码的C风格字符串不同,因为它存储显式长度参数。尽管BSTR的类型为wchar_t*,但无法传递纯文本字符串来代替BSTR

要创建一个字符串,你需要调用SysAllocString一个BSTR

BSTR objPath = ::SysAllocString(L"CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}'"); 
hRes = pSvc->DeleteInstance(
     objPath, 
     WBEM_FLAG_RETURN_IMMEDIATELY, NULL, NULL); 
::SysFreeString(objPath); 

或者,你已经在使用ATL为CComPtr,因为你可以使用CComBSTR,使您的生活更轻松:

CComBSTR objPath(L"CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}'"); 
hRes = pSvc->DeleteInstance(
     objPath, 
     WBEM_FLAG_RETURN_IMMEDIATELY, NULL, NULL); 


注: IWbemLocator::ConnectServer也需要 BSTR s作为参数。文档页面上提供的示例传递的是纯C风格的字符串,因此当呈现无效参数时,接口可能会更宽容一些。

+0

既不适用于'BSTR'也不适用'CComBSTR'。 'BSTR'被typedefed为'OLECHAR *','OLECHAR'为'WCHAR','WCHAR'为'wchar_t'。所以基本上'BSTR'和'wchar_t *'是一样的。 – ST3

+1

@ ST3:'BSTR'和'wchar_t *'在C或C++中是相同的**类型**,但具有根本不同的语义。 [BSTR](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069.aspx)是一种组合数据类型,由长度前缀,数据字符串和终止符组成。作为一个计数的字符串,它可以包含嵌入的NUL字符。另一方面,C风格的字符串是零终止的,因此不能包含NUL字符,因为它不保留显式长度前缀。使用真正的“BSTR”时会得到什么样的错误代码? – IInspectable

+0

错误代码保持不变,“0x80041008”。 – ST3