使用C+删除WMI实例+; 我发现了一些具有Wi实例删除的C和VBS样本,但是我需要用C++实现。

使用C+删除WMI实例+; 我发现了一些具有Wi实例删除的C和VBS样本,但是我需要用C++实现。,c++,windows,winapi,com,wmi,C++,Windows,Winapi,Com,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))

我的示例代码:

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;
CoInitialize(空);
HRESULT hRes;
//获取WMI的初始定位器
CComPtr pLoc=NULL;
hRes=CoCreateInstance(CLSID_WbemLocator,NULL,CLSCTX_INPROC_服务器,IID_IWbemLocator,(LPVOID*)&pLoc);
如果(失败(hRes))
返回1;
//通过IWbemLocator::ConnectServer方法连接到WMI
CComPtr pSvc=NULL;
//与当前用户连接到根命名空间,并获取指针pSvc以进行IWbemServices调用。
hRes=pLoc->ConnectServer(L“ROOT\\SUBSCRIPTION”,NULL、NULL、0、NULL、0、0和pSvc);
如果(失败(hRes))
返回1;
hRes=pSvc->DeleteInstance(
L“CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}',
WBEM_标志_立即返回_,空,空);
返回0;
根据我发现的,我的代码应该可以工作。我肯定有
CommandLineEventConsumer
名为
{709782F3-E860-488E-BD8A-89FBC8C1495C}

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

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

第一个参数是
BSTR
BSTR
与UTF-16编码的C样式字符串的不同之处在于,它存储一个显式长度参数。即使
BSTR
的类型为
wchar\u t*
,也不能传递纯字符串文本来代替
BSTR

要从字符串文本创建
BSTR
,需要调用:

或者,由于您已经在为
CComPtr
使用ATL,您可以使用它来简化您的生活:

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


注:还需要
BSTR
s作为参数。文档页面上提供的示例确实传递了一个普通的C样式字符串,因此当呈现无效参数时,
IWbemLocator
接口可能更宽容。

我找到了两种解决方案:

1.立即移除
WBEM\u标志\u返回\u
标志

_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);
\u bstr\u t objPath(L“CommandLineEventConsumer.Name='{709782F3-E860-488E-BD8A-89FBC8C1495C}'”;
CComPtr pRes=NULL;
hRes=pSvc->DeleteInstance(objPath、WBEM\u FLAG\u RETURN\u立即、NULL和pRes);

没有做过很多调查,但它是双向的。看起来规格不是100%正确。

它既不适用于
BSTR
也不适用于
CComBSTR
。另外,
BSTR
类型定义为
oclehar*
oclehar
类型定义为
WCHAR
WCHAR
类型定义为
WCHAR
。基本上,代码< > BSTR 和 WCARAYT*< /COD>是相同的。@ ST3:<代码> BSTR 和 WCARYT**>代码>在C或C++中是相同的类型,但语义上有根本不同。是一种复合数据类型,由长度前缀、数据字符串和终止符组成。作为计数字符串,它可以包含嵌入的NUL字符。另一方面,C样式的字符串以零结尾,因此不能包含NUL字符,因为它不维护显式长度前缀。使用real
BSTR
时,您会收到什么错误代码?
_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);