5

WMIで何かをしたい(イベント通知を受信する)ので、MSDNWebサイトの簡単な例から始めます。

WMIを介したイベント通知の受信

このプログラムは、WMIを介してイベント通知(プロセスの作成)を受信し、イベントの受信時に関数EventSink::Indicateを呼び出します。

上記のリンク(コピー/過去)で同じコードを使用しましたが、1つ変更しました:クラス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 に答える