如何读写WINDOWS2000的日志

以前写了一个关于如何读写WINDOWS2000的日志的小应用程序,通过vc知识库查到相关信息。

今天突然想起,赶快记录下来,以便作为一个资料积攒。全文如下。

 

如何读写WINDOWS2000的日志
作者:king_koo

下载本文示例工程

一些大型应用程序会把他们的一些事件写到日志里面去,比如sql server,norton,iis.google了一下,
网上关于这方面的资料并不是很完整,于是整理加工了一下. 下面是我看msdn,google及自己摸索得到的一点
体会,共享.

.注册事件源.(需以administrator登陆本机才行)
你需要为你的应用程序注册一个事件源,以表明那些是属于你应用程序的事件.

   HKEY hk;

        ULONG disposition, allowed;

        char szName[256];

        strcpy(szName,"SYSTEM//CurrentControlSet//Services//Eventlog//Application//");

        strcat(szName,"CMCard");

        if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,szName,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,

               NULL,&hk,&disposition))//为事件源建一个键

        { 

               printf("Unable to create registry key");

               return;

        }

        strcpy (szName,"%SystemRoot%//System//MYDLL.DLL");

        if(RegSetValueEx(hk,"EventMessageFile",0,REG_EXPAND_SZ,(LPBYTE)szName,strlen(szName)+1))

        {//为事件源指定一个解释事件的事件dll.

               printf("Unable to create/set registryvalue (message DLL name)");

               return;

        }

        allowed=EVENTLOG_ERROR_TYPE|EVENTLOG_WARNING_TYPE|EVENTLOG_INFORMATION_TYPE;

        if (RegSetValueEx(hk,"TypesSupported",0,REG_DWORD,(LPBYTE)&allowed,sizeof(DWORD)))

        {//为事件源指定类型

               printf("Unable to create/set registry value (message types)");

               return;

        }

        RegCloseKey(hk);


.编写事件dll.(用于解释事件id表示的内容)
mc.exe(vc自带)编译一个*.mc文件,生成*.h,*.rc,*.bin,再用他们生成一个资源dll(vc生成一个空
win32dll
框架,把他们加进来编译),system目录下.
下面是一个mc文件的样板:

;//begin==============================================================

;#ifndef __CMCARD_H__

;#define __CMCARD_H__

LanguageNames=(Chinese=2052:MSG0052)

 

SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS

               Informational=0x1:STATUS_SEVERITY_INFORMATIONAL

               Warning=0x2:STATUS_SEVERITY_WARNING

               Error=0x3:STATUS_SEVERITY_ERROR

              )

 

 

MessageId=1000 Severity=Success SymbolicName=CM_CARD_STATUS_OK

Language=Chinese

CMCard的状态良好.

.

 

MessageId=1001 Severity=Success SymbolicName=CM_CARD_STATUS_BED

Language=Chinese

CMCard出错了,原因可能是%1.

.

 

;#endif  //__CMCARD_H__

;//end================================================================


说明:默认的语言是英语,此时"LanguageNames="那句可以省略;
%1
表示从ReportEvent传来的参数;
注意注释时";"";//"的不同用法.mc编译器会忽略";"后面的字符,但会把他们写到*.h文件里.

.写日志的方法.

//vc

BOOL syslog(DWORD dwID,char*str,WORD wType)//参数:事件id;事件附加信息;事件类型

{

        HANDLE hd=RegisterEventSource(NULL,"CMCard");//指定/打开事件源

        char* buff[1];

        buff[0]=str;

        int i;

        if(hd){

                i=ReportEvent(hd,wType,0,dwID,NULL,1,0,(LPCTSTR*)buff,NULL);//写日志

               DeregisterEventSource(hd);//关闭事件源

               if(i)return TRUE;

        }

        return FALSE;

}

''vb

Private Declare Function ReportEvent Lib "advapi32" Alias "ReportEventA" (ByVal hEventLog As Long, _

    ByVal wType As Long, ByVal wCategory As Long, ByVal dwEventID As Long, ByVal lpUserSid As Long, _

    ByVal wNumStrings As Long, ByVal dwDataSize As Long, lpStrings As Any, lpRawData As Any) As Long

''注意这个声明,api text viewer的是不同的.注意As Any的妙用.

Function sysLog(byval lngID as long,byval strMsg As String,byval lngType as long) As Boolean

    Dim hd As Long

    Dim ret As Integer

    hd = RegisterEventSource("", "CMCard")

    If hd <> 0 Then

        ret = ReportEvent(hd, lngType, 0, lngID, 0&, 1, 0, strMsg, 0)

        DeregisterEventSource hd

    End If

    If ret <> 0 Then

        sysLog = True

    Else: sysLog = False

    End If

End Function


.读日志的例子.

void CEventDlg::OnButton3()

{//参考http://www.codeproject.com/system/sysevent.asp

        HANDLE hdle;

        EVENTLOGRECORD *ptr;

        BYTE buff[4096];

        DWORD read_len, next_len;

        ptr=(EVENTLOGRECORD *)&buff;

        hdle=OpenEventLog("", "Application");// System

        if (hdle==NULL)

        {

               MessageBox("打开日志失败");

        }

        else

        {

               long mRet;

               char lpszSourceName[255]={0};

               char lpszComputerName[255]={0};

               unsigned uStepOfString;

               char* pStrings;

               char szExpandedString[1024]={0};

                while(ReadEventLog(hdle,EVENTLOG_FORWARDS_READ|EVENTLOG_SEQUENTIAL_READ,

                       1,ptr,sizeof(buff),&read_len,&next_len))

               {

                       mRet=ptr->EventID;//事件id

                       mRet=ptr->EventType;//事件类型

                       mRet=ptr->TimeWritten;//

                       mRet=ptr->NumStrings;//

                       mRet=ptr->Length;//

                       mRet=sizeof(EVENTLOGRECORD);

                       strcpy(lpszSourceName, (LPTSTR)((LPBYTE)ptr +mRet));//事件源

                       mRet+= strlen(lpszSourceName) + 1;

                       strcpy(lpszComputerName, (LPTSTR)((LPBYTE)ptr + mRet));//机器名

                       mRet+= strlen(lpszComputerName) + 1;

                       if(ptr->UserSidLength>0){;}//

                       mRet=ptr->DataOffset-ptr->StringOffset;

                       if(mRet>0)//事件描述

                       {

                               pStrings=new char[mRet];

                               memcpy(pStrings,(LPBYTE)ptr+ptr->StringOffset,mRet);

                               uStepOfString=0;

                               for(int x=0;x<ptr->NumStrings;x++)

                               {

                                      if(x==0)

                                      {

                                              strcpy(szExpandedString, (TCHAR *)pStrings + uStepOfString);

                                              if(x<(UINT)ptr->NumStrings - 1)strcat(szExpandedString, ",");

                                      }

                                      else strcat(szExpandedString, pStrings + uStepOfString);

                                      uStepOfString = strlen(pStrings + uStepOfString) + 1;

                               }

                               delete [] pStrings;

                       }

                       MessageBox(lpszSourceName,szExpandedString);

               }

               CloseEventLog(hdle);

        }

}

.源代码的使用与运行结果
本文附带的示例工程对WIN2K日志的读写进行了演示,使用时先编译mydll,并拷贝到system目录下,然后编译event工程。运行结果可以使用事件查看器查看:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值