日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

WMI技术介绍和应用——Event Consumer Provider

發布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WMI技术介绍和应用——Event Consumer Provider 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? 在《WMI技術介紹和應用——Event Provider》和《WMI技術介紹和應用——接收事件》中,我們展現了如何處理和事件相關的WMI知識。而《WMI技術介紹和應用——接收事件》一文則主要講解了如何查詢事件,這種查詢是在我們進程存在時發生的,一旦我們進程不存在了,這種查詢也無法執行。我們將這種行為稱為消費事件,我們執行查詢的進程叫做“事件臨時消費者”。相對應的,WMI還存在“事件永久消費者”,它并不寄生我們的編寫的進程中。本文主要講解“事件永久消費者”的編寫方法。(轉載請指明出于breaksoftware的csdn博客)

? ? ? ? 由于VS2005沒有這種模板,所以我便使用事件提供者模板生成了一個工程,并對這個工程進行改造。我們先從mof文件出發

? ? ? ? 由于我們不需要注冊事件提供者,所以我們刪除instance?of?__EventProviderRegistration內容。

? ? ? ? 我們先要聲明一個事件消費類

class TestEventConsumer : __EventConsumer 
{[key] string name;[write] string value;
};

? ? ? ? 實例化該類

instance of TestEventConsumer as $Consumer
{name = "TestEventConsumer_Name1";value = "TestEventConsumer_Value";
};

? ? ? ? 再注冊一個事件消費者提供者實例

instance of __EventConsumerProviderRegistration
{Provider = $EventConsumer;ConsumerClassNames = {"TestEventConsumer"};
};

? ? ? ? ConsumerClassNames是一個數組,它記錄了事件消費者名。

? ? ? ? 然后要實例化一個篩選器

instance of __EventFilter as $Filter
{Name = "TestEventFilter";QueryLanguage = "WQL";Query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_USBCOntrollerDevice'";EventNamespace = "\\\\.\\root\\CIMV2";
};

? ? ? ? 其中定義了篩選器的名字、查詢的語言、查詢的命令和需要查詢的命名空間。如果沒有指定EventNamespace,則使用該mof中默認的命名空間。在本例中,我們要監控USB設備的創建,故要監控CIMV2空間。這兒需要注意的是,我們可以Query內部事件或者外部事件。

? ? ? ? 最后我們將篩選器綁定到消費者上。

instance of __FilterToConsumerBinding
{Consumer = $Consumer;Filter = $Filter;
};

? ? ? ? 如此,我們便將mof文件構建好了。

? ? ? ? 我們再回到cpp文件中,我們首先要定義一個事件消費者Sink

class CEventConsumerSink:public CComObjectRootEx<CComMultiThreadModel>,public IWbemUnboundObjectSink 
{ 
public:CEventConsumerSink() {}~CEventConsumerSink(){}BEGIN_COM_MAP(CEventConsumerSink) COM_INTERFACE_ENTRY(IWbemUnboundObjectSink) END_COM_MAP() // IWbemUnboundObjectSink 
public: STDMETHOD(IndicateToConsumer)(IWbemClassObject* pLogicalConsumer, long lNumObjects, IWbemClassObject** apObjects);
};

? ? ? ? 我們要實現IndicateToConsumer方法,將事件傳到到該方法中處理

STDMETHODIMP CEventConsumerSink::IndicateToConsumer(IWbemClassObject* pLogicalConsumer, long lNumObjects, IWbemClassObject** apObjects)
{ObjectLock lock(this); HRESULT hr = WBEM_S_NO_ERROR; CComVariant varClass; hr = pLogicalConsumer->Get(CComBSTR("__CLASS"), 0, &varClass, 0, 0);if (0 == _wcsicmp(V_BSTR(&varClass), L"TestEventConsumer")) {for (long lIndex = 0; lIndex < lNumObjects; lIndex++) {CComVariant varEventType;hr = apObjects[lIndex]->Get(CComBSTR("TargetInstance"), 0, &varEventType, 0, 0);CComQIPtr<IWbemClassObject> spEvent = V_UNKNOWN(&varEventType);CComVariant varEventTypeClass;hr = spEvent->Get(CComBSTR("__CLASS"), 0, &varEventTypeClass, 0, 0);OutputTrace("CEventConsumerSink::IndicateToConsumer");    }  }else {hr = WBEM_E_NOT_FOUND;}return hr; 
}

? ? ? ? 這段邏輯,我們獲取事件名稱,并檢測其是否是我們需要監控的事件。如果是,則遍歷事件數組——發來的事件是一批的。

? ? ? ? 然后我們改造主類。事件消費者提供者不需要繼承IWbemInstProviderImpl,但是要繼承IWbemEventConsumerProvider。于是我們在模板生成的代碼中將其他無關的方法去掉

class ATL_NO_VTABLE CEventConsumer : public CComObjectRootEx<CComMultiThreadModel>,public CComCoClass<CEventConsumer, &CLSID_EventConsumer>,public IWbemProviderInit,public IWbemEventConsumerProvider
{    public:CEventConsumer(){                  }~CEventConsumer(){}DECLARE_REGISTRY_RESOURCEID(IDR_EVENTCONSUMER)DECLARE_NOT_AGGREGATABLE(CEventConsumer)BEGIN_COM_MAP(CEventConsumer)COM_INTERFACE_ENTRY(IWbemProviderInit)COM_INTERFACE_ENTRY(IWbemEventConsumerProvider)END_COM_MAP()//IWbemProviderInitHRESULT STDMETHODCALLTYPE Initialize( __in_opt LPWSTR pszUser,LONG lFlags,__in LPWSTR pszNamespace,__in_opt LPWSTR pszLocale,IWbemServices *pNamespace,IWbemContext *pCtx,IWbemProviderInitSink *pInitSink);// IWbemEventConsumerProviderHRESULT STDMETHODCALLTYPE FindConsumer( /* [in] */ IWbemClassObject *pLogicalConsumer,/* [out] */ IWbemUnboundObjectSink **ppConsumer);};

? ? ? ??Initialize中刪除模板生成的多余代碼就可以了,我們主要要實現的就是FindConsumer方法

STDMETHODIMP CEventConsumer::FindConsumer( /* [in] */ IWbemClassObject *pLogicalConsumer,/* [out] */ IWbemUnboundObjectSink **ppConsumer)
{HRESULT hr = WBEM_E_NOT_FOUND;*ppConsumer = NULL;CComVariant varClass;hr = pLogicalConsumer->Get(L"__Class", 0, &varClass, 0, 0);if (0 == _wcsicmp(V_BSTR(&varClass), L"TestEventConsumer")) {CComObject<CEventConsumerSink>* pEventSink = NULL;hr = CComObject<CEventConsumerSink>::CreateInstance(&pEventSink);if (FAILED(hr)) {return hr;}hr = pEventSink->QueryInterface(IID_IWbemUnboundObjectSink, (LPVOID*)ppConsumer);if (FAILED(hr)) {return hr;}}else {hr = WBEM_E_NOT_FOUND;}return hr;
}

? ? ? ? 這段邏輯我們在檢測完消費者類是否正確后,就去獲取消費者指針。

? ? ? ? 如此Event Consumer Provider便搭建起來了。

總結

以上是生活随笔為你收集整理的WMI技术介绍和应用——Event Consumer Provider的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。