2017-02-26 58 views
1

我想在每次打開時檢索每個進程的信息。我不想僅僅寫一個「愚蠢的」循環來循環所有打開的進程,並檢查什麼時候發生變化,我想做一些更優雅的事情。 我想查詢的過程中創建事件,並從這樣的事件檢索有關進程的信息: 我使用WMI異步查詢Win32_Process的情況下,像這樣的__InstanceCreationEvent:讀取並顯示來自變種VT_UNKNOWN的數據

hr = pSvc->ExecNotificationQueryAsync(
      _bstr_t("WQL"), 
      _bstr_t("SELECT * " 
       "FROM __InstanceCreationEvent WITHIN 1 " 
       "WHERE TargetInstance ISA 'Win32_Process'"), 
      WBEM_FLAG_SEND_STATUS, 
      NULL, 
      pStubSink); 

ExecNotificationQueryAsync檢索事件,它會調用用戶執行的IWbemObjectSink::Indicate方法,並將該事件作爲IWbemClassObject接口傳遞給它。 (它傳遞一個指向所有這些事件的數組的指針)。 現在是這個問題。我使用IWbemClassObject::Get爲了從TargetInstance屬性(這是Win32_Process實例)獲取數據。但是,Get函數會將結果輸出到VARIANT。當檢查結構的vt成員時,我發現包含有效數據的成員是punkVal。 punkVal的類型是IUnknown。 基本上我的問題如下: 如何通過punkVal獲得Win32_Process實例? 這是我實現Indicate方法:

HRESULT EventSink::Indicate(LONG lObjectCount, 
IWbemClassObject **apObjArray) 
{ 

    for (int i = 0; i < lObjectCount; i++) 
    { 
     IWbemClassObject * InstanceCreationEventInterface = apObjArray[i]; 

     VARIANT v; 
     BSTR strClassProp = SysAllocString(L"TargetInstance"); 
     HRESULT hr; 
     hr = InstanceCreationEventInterface->Get(strClassProp, 0, &v, 0, 0); 
     SysFreeString(strClassProp); 

     if (SUCCEEDED(hr) && (V_VT(&v) == VT_UNKNOWN)) 
     { 
      wcout << (&v)->punkVal << endl; //How do I use punkVal here to get the Win32_Process instance? 
     } 
     else 
     { 
      wprintf(L"Error in getting specified object\n"); 
     } 
     VariantClear(&v); 
    } 

    return WBEM_S_NO_ERROR; 
} 

由於punkVal的類型爲IUnknown*,真正可用於檢索實例IUnknown::QueryInterface但是我真的沒有看到任何方式使用此方法的唯一方法獲取Win32_Process實例。

任何幫助將不勝感激。

+2

TargetInstance也是IWbemClassObject,這樣你就可以齊作IWbemClassObject在您have.http了的IUnknown://stackoverflow.com/questions/28897897/c-monitor -process-creation-and-termination-in-windows –

+0

@SimonMourier謝謝你,這解決了我的問題。我一直在痛苦這個問題太久:) – Daniel

回答