寫系統日誌的步驟及注意事項

 

[ 2007-12-2 15:08:00 | By: 吃遍天下 ]
 
0

  最近幾日,由於工作需要,研究瞭如何寫系統日誌(就是在事件查看器才能看到的日誌記錄),這是從網上收集的資料,加以消化之後,作爲編程總結,寫在此處。

  要想將消息文字顯示在系統日誌中就必須使用一個API函數--ReportEvent,用於寫入事件。函數原型爲

BOOL ReportEvent (
  HANDLE hEventLog,           //事件源句柄
  WORD wType,      //事件類型(警告類型、錯誤類型、常規消息類型... ...)   
  WORD wCategory,
  DWORD dwEventID,           //事件ID
  PSID lpUserSid,
  WORD wNumStrings,         //參數字符串的個數
  DWORD dwDataSize,
  LPCTSTR* lpStrings,  //參數字符串,它是指向一個包含以NULL爲結尾的字符串爲元素的數組的指針 
  LPVOID lpRawData
);


      以上給出了程序中要用的參數的解釋,由此我們可以看出我們還要有一個事件源,而什麼事件源呢?其實就是保存在註冊表中特定路徑下的一個子鍵

HKEY_LOCAL_MACHINE
     SYSTEM
          CurrentControlSet
               Services
                    EventLog
                         Application
                              AppName

      而要獲得事件源句柄,要調用hEventLog = RegisterEventSource( NULL, _T("AppName") ); 如果系統在註冊表中找到了“AppName”的子鍵的話,那麼就返回一個有效事件源句柄了。
      這個子鍵中有一個非常重要的信息 EventMessageFile 類型爲REG_EXPAND_SZ 而鍵值是一個事件消息文件的全名稱路徑,注意這裏又出現了一個新名詞“事件消息文件”,它是一個DLL或EXE文件,給出了事件ID和事件描述字符串。它的製作步驟是:

1、首先要寫一個文本類型的消息文件,這個文件必須是如下格式

基本格式:
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
 MessageId=xxx
 SymbolicName=IDS_EVT_MYDEFINE
 Language=English
 
 mydefine event string goes here.if there's parameters use %1 %2...
 .
 //must use . to end one event message define.
 
 MessageId=xxx//next block...
 .
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
如果使用中文,在文件最初定義
LanguageNames=(Chinese=0x804:MSG00804)//0x804CodePageMSG00804爲定義文件名稱(mc輸出的.bin文件)。然後替換基本格式中的Language字段,如下Language=Chinese
 
說明:默認的語言是英語,此時"LanguageNames="那句可以省略;
%1,%2等表示從ReportEvent傳來的參數;
注意註釋時";"與";//"的不同用法.mc編譯器會忽略";"後面的字符,但會把他們寫到*.h文件裏.
 
如果支持多種語言,則如下定義
LanguageNames=(English=0x409:MSG00409)
LanguageNames=(Chinese=0x411:MSG00411)
MessageId=0x1
Severity=Error
Facility=Runtime
SymbolicName=MSG_BAD_COMMAND
Language=English
You have chosen an incorrect command.
Language=Chinese
.
  ④文件必須以一個空行結束,即在最後一個信息定義塊的 '.' 後加回車換行
 
 
2、使用mc編譯此文件.
mc.exeVC帶的工具,路徑參考
C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/Tools/Bin
dos,使用mc編譯文件。如果你的項目使用UNICODE,如下:mc myevt.mc;否則必須加入命令選項:mc myevt.mc -A。將生成的三個文件myevt.rc myevt.h MSG00804.bin

3、製作好這三個文件之後,製作DLL

vc生成一個空win32dll框架,將生成的.rc資源文件編譯即可得到一個DLL文件。(注意:一定要把.bin文件放在同一路徑下,這樣纔會編譯成功的)別忘了在註冊表中創建應有的鍵。

  最後在創建一個應用程序,把生成的.h文件加入工程中,用RegisterEventSource(NULL," myevt ")打開事件源,返回一句柄,然後以此句柄ReportEvent,即完成日誌的寫入。可在事件管理器中察看:右鍵我的電腦管理系統工具事件視圖。具體事件是屬於“應用程序”,“系統”還是“安全”,則看ReportEvent時的參數了。
      注意事項:在使用ReportEvent函數時一定要注意倒數第二個參數 LPCTSTR* lpStrings,它是指向一個包含以NULL爲結尾的字符串爲元素的數組的指針,如果沒注意到,有可能在查看器中看不到記錄!
      最後,附上我所收集的程序段:
//////////////////////////////////CMPServiceMsg.mc/////////////////////////////////////
LanguageNames=(Chinese=2052:MSG0052)
MessageId = 1000
SymbolicName = EVMSG_INFORMATION
Language=Chinese
常規消息:%1
如需進一步幫助,請與[email protected]聯繫!
.
MessageId =
SymbolicName = EVMSG_ERROR
Language=Chinese
錯誤原因:%1
如需進一步幫助,請與[email protected]聯繫!
.
//////////////////////////////////////////////////////////////////////////////////////////////////////////
 
/////////////////////////////////可執行程序//////////////////////////////////////////////////
#i nclude "stdafx.h"
#i nclude <Windows.h>
#i nclude "cmpservicemsg.h"
void LogEvent( WORD wType, DWORD dwID, const TCHAR* pszFormat, ...)
{
 /*EVENTLOG_ERROR_TYPE EVENTLOG_INFORMATION_TYPE*/
 HANDLE hEventLog=NULL;
 TCHAR* pBuf[1];
 TCHAR buf[1024]={0};
 va_list arglist;
 va_start(arglist, pszFormat);
 _vstprintf_s(buf, 1023, pszFormat, arglist);
 va_end(arglist);
 _tcscat_s(&buf[_tcslen(buf)], 1023-_tcslen(buf), _T("/n/n"));
 pBuf[0] = buf;
 /* 打開事件源 */
 hEventLog = RegisterEventSource( NULL, _T("CMPService") );
 if( NULL != hEventLog )
 {
  /* 內容寫入 */
  ReportEvent( hEventLog,
   wType,
   0,
   dwID,
   NULL,
   1,
   0,
   (LPCTSTR*)pBuf,
   NULL );  
 }
 DeregisterEventSource(hEventLog);
}
int _tmain(int argc, _TCHAR* argv[])
{
 LogEvent(EVENTLOG_INFORMATION_TYPE, EVMSG_INFORMATION, _T("Kao,這樣都行呀!%s真厲害!--------%d"), _T("趙文卓"), 2);
 LogEvent(EVENTLOG_ERROR_TYPE, EVMSG_ERROR, _T("瓦靠!不行了吧! %s還要努力呀!-----%d"), _T("趙文卓"), 3);
 return 0;
}
/////////////////////////////////////////////////////////////////////////////////
 
////////////////////////註冊表項////////////////////////////////
 
 
//////////////////////////////////////////////////////////////////

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章