写系统日志的步骤及注意事项

 

[ 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)//0x804 CodePage MSG00804 为定义文件名称( 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.exe VC 带的工具 ,路径 参考
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
如需进一步帮助,请与sxzy_hxjr@vip.163.com联系!
.
MessageId =
SymbolicName = EVMSG_ERROR
Language=Chinese
错误原因:%1
如需进一步帮助,请与sxzy_hxjr@vip.163.com联系!
.
//
 
/可执行程序//
#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;
}
/
 
注册表项
 
 
//

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值