使用C++删除WMI实例
问题描述:
我发现了一些使用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;
据我发现here和here,我的代码应该工作。我肯定会CommandLineEventConsumer
命名为{709782F3-E860-488E-BD8A-89FBC8C1495C}
我的代码失败在IWbemServices::DeleteInstance
,错误代码0x80041008
(其中一个参数来调用的是不正确的)。
如果有人在我的代码中发现错误,我将不胜感激。或者可能需要一些特权才能做到这一点?
答
我发现两种解决方案:
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%正确的。
答
注: IWbemLocator::ConnectServer也需要
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风格的字符串,因此当呈现无效参数时,接口可能会更宽容一些。
既不适用于'BSTR'也不适用'CComBSTR'。 'BSTR'被typedefed为'OLECHAR *','OLECHAR'为'WCHAR','WCHAR'为'wchar_t'。所以基本上'BSTR'和'wchar_t *'是一样的。 – ST3
@ ST3:'BSTR'和'wchar_t *'在C或C++中是相同的**类型**,但具有根本不同的语义。 [BSTR](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069.aspx)是一种组合数据类型,由长度前缀,数据字符串和终止符组成。作为一个计数的字符串,它可以包含嵌入的NUL字符。另一方面,C风格的字符串是零终止的,因此不能包含NUL字符,因为它不保留显式长度前缀。使用真正的“BSTR”时会得到什么样的错误代码? – IInspectable
错误代码保持不变,“0x80041008”。 – ST3