【问题标题】:Deleting WMI instance with C++使用 C++ 删除 WMI 实例
【发布时间】:2016-05-12 14:03:12
【问题描述】:

我找到了一些用于 WMI 实例删除的 C# 和 VBS 示例,但是我需要使用 C++ 实现。

我的示例代码:

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(调用的参数之一不正确)。

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

【问题讨论】:

    标签: c++ windows winapi com wmi


    【解决方案1】:

    IWbemServices::DeleteInstance 的第一个参数是BSTRBSTR 与 UTF-16 编码的 C 样式字符串不同,它存储显式长度参数。即使BSTRwchar_t* 类型,您也不能传递纯字符串文字来代替BSTR

    要从字符串文字创建BSTR,您需要调用SysAllocString

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

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

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


    注意:IWbemLocator::ConnectServer 也需要BSTRs 作为参数。文档页面上提供的示例确实传递了一个纯 C 样式的字符串,因此当提供无效参数时,IWbemLocator 接口可能更宽容。

    【讨论】:

    • 它不适用于BSTRCComBSTR。同样BSTR 的类型定义为OLECHAR*OLECHARWCHARWCHARwchar_t。所以基本上BSTRwchar_t*是一样的。
    • @ST3: BSTRwchar_t* 在 C 或 C++ 中是相同的 type,但语义完全不同。 BSTR 是一种复合数据类型,由长度前缀、数据字符串和终止符组成。作为计数字符串,它可以包含嵌入的 NUL 字符。另一方面,C 风格的字符串以零结尾,因此不能包含 NUL 字符,因为它不维护显式长度前缀。使用真正的 BSTR 时,您会得到什么错误代码?
    【解决方案2】:

    我找到了两个解决方案:

    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% 正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 2018-02-26
      • 2013-02-03
      相关资源
      最近更新 更多