首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

在 VC++ 程式中自訂 Vista 事件日誌

     編輯:關於VC++

對 Windows 開發人員與系統管理員而言,Windows Vista 事件日誌較以往有極大提升。對開發人員,Vista 日誌記錄對多種事件與選項展現統一致性;對網管與 IT 專家,提供豐富人機介面管理事件。新日誌記錄方式僅能透過 Windows SDK 新原生函數實現,以下探討如何在程式中實作。

建立與編譯資訊清單檔案

若程式使用新 API 且要將事件記錄至日誌,需建立資訊清單檔案(程式中所有事件的 XML 表現形式)。可使用命令列訊息編譯器 MC.exe,利用資訊清單產生標頭檔(*.h)與資源檔(*.rc)——僅限 C++ 專案使用。(詳細說明請查閱 MSDN,本文僅提及部分。)

資訊清單中最重要的元素是指定哪個「通道」可被寫入。「通道」是 Vista 事件日誌新概念,依接收者與磁碟區為事件提供獨立輸出。範例程式使用兩個通道:操作性與偵錯通道,以下 XML 指定程式將使用這兩種通道引發事件:

<channels>
    <importChannel chid="C1" name="Application"/>
    <channel chid="MyOpChannel"
        name="DotNetPerformance-TechalWriting-EventLogSample/Operational"
        type="Operational" symbol="DOTNETPERFORMANCE"
        isolation="Application" enabled="true"/>
    <channel chid="MyDebugChannel"
        name="DotNetPerformance-TechalWriting-EventLogSample/Debug"
        type="Debug" symbol="DOTNETPERFORMANCE"
        isolation="Application" enabled="true"/>

定義好通道後,需定義範本指定引發事件的基本形態。類似舊版事件日誌 API,Vista 也支援 %1 等置換符,方便以當地語系化文字取代,所有訊息內容可在執行期提供:

<template tid="SimpleEvent" message="$(string.SimpleMessage)">
    <data name="Message" inType="win:UnicodeString"/>
    <UserData>
        <SimpleEvent xmlns="https://manifests.microsoft.com/win/2004/08/windows/simpleevent">
            <ExceptionMessage>%1</ExceptionMessage>
        </SimpleEvent>
    </UserData>
</template>

最後將應用程式實際引發的事件加入資訊清單,為簡單起見,每個通道只定義一個事件,皆使用同一範本:

<event value="1" level="win:Informational" template="SimpleEvent"
    opcode="win:Info" channel="MyOpChannel" symbol="DNP_OP_EVENT"
    message="$(string.SimpleMessage)"/>
<event value="2" level="win:Informational" template="SimpleEvent"
    opcode="win:Info" channel="MyDebugChannel" symbol="DNP_DEBUG_EVENT"
    message="$(string.SimpleMessage)"/>

現在訊息編譯器 mc.exe 即可將資訊清單編譯為標頭檔與資源檔。

引發事件

實際在程式中引發事件相當簡單(至少比定義資訊清單簡單)。訊息編譯器產生的標頭檔包含事件與事件發行者定義,可傳遞給 SDK 函數。對上述資訊清單,標頭檔將包含:

EXTERN_C __declspec(selectany) const
GUID DOTNETPERFORMANCE_TECHNICALWRITING_PUBLISHER
= {0x9cde86c9, 0xdfb9, 0x463f, {0xb2, 0xc5, 0x71, 0xee, 0xc2, 0x32, 0xa6, 0x9c}};
#define DOTNETPERFORMANCEOP 0x10
#define DOTNETPERFORMANCEDEBUG 0x0
EXTERN_C __declspec(selectany) const
EVENT_DESCRIPTOR OP_EVENT = {0x1, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
#define DNP_OP_EVENT_value 0x1
EXTERN_C __declspec(selectany) const
EVENT_DESCRIPTOR DEBUG_EVENT = {0x2, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4000000000000000};
#define DNP_DEBUG_EVENT_value 0x2
#define MSG_SimpleMessage 0xB0000001L

接著在程式碼包含標頭檔:windows.h(主控台程式)、evntprov.h(Windows 事件追蹤)、winevt.h(Vista 日誌宣告);透過 EventRegister 註冊事件發行者:

REGHANDLE hPub = NULL;
EventRegister(&DOTNETPERFORMANCE_TECHNICALWRITING_PUBLISHER, NULL, NULL, &hPub);

引發事件非常簡單:建立事件描述符並傳給 EventWrite:

EVENT_DATA_DESCRIPTOR opEventDesc;
PWSTR pwsOp = L"My Operational Event";
EventDataDescCreate(&opEventDesc, pwsOp, ((ULONG)wcslen(pwsOp)+1)*sizeof(WCHAR));
EventWrite(hPub, &DNP_OP_EVENT, 1, &opEventDesc);

EventDataDescCreate 定義於 evntprov.h,提供較短語法設定 EVENT_DATA_DESCRIPTOR 成員。不再需要寫入事件時,呼叫 EventUnregister(hPub) 取消註冊。

部署與使用

部署前需用以下命令註冊資訊清單:wevtutil install-manifest 清單檔案.xml。Vista 內建 wevtutil 工具會解析資訊清單並加入所需設定至 Vista 日誌;若未執行 wevtutil,事件仍可成功引發,但在事件日誌中不可見。一切正常時,事件將如期出現在日誌中(見下圖)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved