5

我想用 WMI 做一些事情(接收一些事件通知),所以我从 MSDN 网站上的简单示例开始:

通过 WMI 接收事件通知

该程序通过WMI接收事件通知(进程创建),并在接收到事件时调用函数EventSink::Indicate。

我在上面的链接(复制/过去)中使用了相同的代码,但做了一个更改:在 EventSink 类中,函数

HRESULT EventSink::Indicate(long lObjectCount, IWbemClassObject **apObjArray)

我添加了几行来检索对象的属性(对象在 apObjArray 中返回):

 for (int i = 0; i < lObjectCount; i++)
    {
        VARIANT varName;
        hres = apObjArray[i]->Get(_bstr_t(L"Name"),
            0, &varName, 0, 0);
//...
    }

现在 Get(...) 函数返回 WBEM_E_NOT_FOUND (未找到指定的属性),无论我寻找什么(从文档中确定属性在那里......)

请让我知道我错过了什么?!任何帮助表示赞赏。

4

2 回答 2

11

Name属性是TargetInstance对象的一部分,因此您必须获取 TargetInstance 对象的值,然后检索该Name属性的值。

试试这个样本

HRESULT EventSink::Indicate(long lObjectCount,
    IWbemClassObject **apObjArray)
{
   HRESULT hr = S_OK;
   _variant_t vtProp;

    for (int i = 0; i < lObjectCount; i++)
    {

    hr = apObjArray[i]->Get(_bstr_t(L"TargetInstance"), 0, &vtProp, 0, 0);
     if (!FAILED(hr))
     {
       IUnknown* str = vtProp;
       hr = str->QueryInterface( IID_IWbemClassObject, reinterpret_cast< void** >( &apObjArray[i] ) );
       if ( SUCCEEDED( hr ) )
       {
          _variant_t cn;
         hr = apObjArray[i]->Get( L"Name", 0, &cn, NULL, NULL );
          if ( SUCCEEDED( hr ) )
          {
            if ((cn.vt==VT_NULL) || (cn.vt==VT_EMPTY))
             wcout << "Name : " << ((cn.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
            else
             wcout << "Name : " << cn.bstrVal << endl;
          }
          VariantClear(&cn);


       }
     }
     VariantClear(&vtProp);

    }

    return WBEM_S_NO_ERROR;
}
于 2012-10-01T03:14:13.850 回答
0

上面的例子似乎有内存泄漏。

IUnknown* str = vtProp;

此赋值使用 _variant_t 类的运算符 IUnknown*,它隐式调用对象上的 AddRef()。所以 str->Release() 需要在使用后调用,因为

VariantClear(&vtProp);

不足以减少对象的引用计数。

于 2020-06-29T13:24:38.433 回答