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

歡迎訪問 生活随笔!

生活随笔

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

生活经验

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

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

? ? ? ? 在《WMI技術介紹和應用——Instance/Method Provider》一文中,我們介紹了Instance和Method Provider的編寫方法。本文我們將介紹更有意思的“事件提供者”。在《WMI技術介紹和應用——事件通知》中,我們曾經提到事件是分為兩種:intrinsic event和extrinsic event。這兩種事件提供者在編寫上也非常類似,我們先以extrinsic event為例。(轉載請指明出于breaksoftware的csdn博客)

intrinsic event provider

? ? ? ? 之前生成工程的過程和《WMI技術介紹和應用——Instance/Method Provider》中介紹的一致,但是我們這次要新增的ATL class則不同

? ? ? ? 在”名稱“頁,我們在short name中填上我們事件提供者的名稱”TestEvent",其他輸入框內容將自動生成。

? ? ? ? 事件類型我們選擇extrinsic event,其他不填

? ? ? ? 在“屬性”頁,將Threading model設置為Both。Support選項都勾選上

? ? ? ? 執行完之后,我們就生成了一個mof文件、一個TestEvent.h和TestEvent.cpp文件。我們繼續從mof文件入手,我們申明一個事件類

[Locale(1033) : ToInstance,UUID("{E5EDE7F6-D9F9-4195-8E97-643B71F2FB91}") : ToInstance] 
class ClassEventInstance: __ExtrinsicEvent 
{
string name = "CIN";
string value = "CIV";
};

? ? ? ? 然后注冊一個事件提供者,并指定查詢命令

instance of __EventProviderRegistration
{provider = $TestEvent;EventQueryList = {"select * from ClassEventInstance"};
};

? ? ? ? 再回到cpp代碼文件,首先我們要修改類名

const static WCHAR * s_pMyClassName = L"ClassEventInstance"; 

? ? ? ? 其次我們要修改AccessCheck函數,刪除掉這行,否則我們查詢不會成功

hr = WBEM_E_ACCESS_DENIED;

? ? ? ? 我們需要修改ProvideEvents函數,在該函數末尾新增如下邏輯

    HANDLE hThread = (HANDLE)_beginthread(ThreadRoutine, 0, this);CloseHandle(hThread);

? ? ? ? 我們啟動一個線程,用于事件的發送。我們傳入this指針只是為了之后調用我們類中的一個方法。我們看下線程函數

static void ThreadRoutine(void* param) {OutputTrace("CTestEvent::ThreadRoutine");CoInitializeEx(NULL, COINIT_MULTITHREADED);CTestEvent* pThis = (CTestEvent*)(param);while(true) {Sleep(1000*2);pThis->FireEvent();}CoUninitialize();
};

? ? ? ? 這段邏輯,我們在一個死循環中每隔兩秒鐘觸發一次事件——FireEvent。FireEvent本來是模板自動生成的,而我們借用它實現事件的觸發。這兒需要注意一個文件,本文主要講解搭建的關鍵步驟,而對很多其他細節和安全問題沒有做過多處理,否則就喧賓奪主了。比如本文中所提到的線程執行函數,其實存在線程安全問題,而我又不想引入COM跨線程問題,所以就如此簡單粗暴的編寫。

STDMETHODIMP CTestEvent::FireEvent()
{HRESULT hr = WBEM_S_NO_ERROR;ATLASSERT(m_pEventClass);CComPtr<IWbemClassObject> pInstance;hr = m_pEventClass->SpawnInstance(0, &pInstance);if(FAILED(hr)) {return hr;}CComVariant value;value.vt = VT_BSTR;value.bstrVal = CComBSTR("notepad.exe");pInstance->Put(L"name", 0, &value, 0);return m_pSink->Indicate(1, &(pInstance.p) );
}

? ? ? ? 我們Spawn一個實例,然后填充它的一些屬性,最后將該對象放入客戶端可以訪問的sink中。
? ? ? ? 我們使用之前實現的查詢類查詢該事件

    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);CAsynNotifyQuery<CInstanceEvent> recvnotify(L"root\\default", L"SELECT * FROM ClassEventInstance", hEvent);recvnotify.ExcuteFun();

? ? ? ? 我們即可以看到結果

extrinsic event provider? ? ? ??

? ? ? ? extrinsic event provider實現講完了,我們再講講intrinsic event provider。工程向導方面和extrinsic event provider基本相同,只是在WMI Class頁中選擇intrinsic event。我們對新的provider取名為IntrinsicEvent。我們也從mof入手,看看怎么修改

[
dynamic : ToInstance, 
provider("IntrinsicEvent") : ToInstance, // uses the TestInstance Provider
ClassContext("whatever!"),          // information is dynamically// supported by the provider
DisplayName("IntrinsicClassInstance"): ToInstance
]                                    class IntrinsicClassInstance 
{
[key]
string name = "CIN";
[PropertyContext("IntrinsicClassInstance_Member")]
string value = "CIV";
};

? ? ? ? 首先我們定義Event的類名——IntrinsicClassInstance,并申明其有兩個屬性——name和value。其次我們我們修改下事件提供者注冊對象

instance of __EventProviderRegistration
{provider = $IntrinsicEvent;EventQueryList = {"select * from __InstanceCreationEvent where TargetInstance isa \"IntrinsicClassInstance\""};
}; 

? ? ? ? 從WQL的寫法我們可以發現,這種寫法和檢測進程創建的Win32_Process類類似,這就是內部(Intrinsic)事件的特點。cpp的修改和extrinsic event provider中介紹的過程類似,只是Intrinsic沒有FireEvent方法,那我們就自己申明和定義一個

STDMETHODIMP CIntrinsicEvent::FireEvent()
{HRESULT hr = WBEM_S_NO_ERROR;ATLASSERT(m_pEventClass);CComPtr<IWbemClassObject> pInstance;hr = m_pDataClass->SpawnInstance(0, &pInstance);if(FAILED(hr)) {OutputTrace("CIntrinsicEvent::FireEvent1");return hr;}CComVariant value;value.vt = VT_BSTR;value.bstrVal = CComBSTR("notepad.exe");pInstance->Put(L"name", 0, &value, 0);CComPtr<IWbemClassObject> pEventInstance;hr = m_pEventClass->SpawnInstance(0, &pEventInstance);if(FAILED(hr)) {return hr;}CComVariant varTargetInst(pInstance);pEventInstance->Put(L"TargetInstance", 0, &varTargetInst, 0);return m_pSink->Indicate(1, &(pEventInstance.p) );
}

? ? ? ? 我們將新生成的實例放入到pEventInstance實例的"TargetInstance"中,這也和上面的WQL的“TargetInstance isa \"IntrinsicClassInstance\"”相對應。pEventInstance實例的類是我們在模板基礎上新增的,我們要修改Initialize函數,新增

hr = m_pNamespace->GetObject(CComBSTR("__InstanceCreationEvent"), 0, pCtx, //passing IWbemContext pointer to prevent deadlocks&m_pEventClass, NULL);
if (FAILED(hr)) {return hr;
}

? ? ? ?我們使用如下代碼訪問該事件

    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);CAsynNotifyQuery<CInstanceEvent> recvnotify(L"root\\default", L"SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'IntrinsicClassInstance'", hEvent);recvnotify.ExcuteFun();

? ? ? ? 我們可以得到如下結果


? ? ? ? 工程鏈接:http://pan.baidu.com/s/1o6QcgPW 密碼:4l5v

總結

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

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