6.3 事件记录.htm

来自「Windows2000后台服务程序开发手册」· HTM 代码 · 共 338 行 · 第 1/3 页

HTM
338
字号
    <TD class=mm vAlign=top><BR>
      <DIV align=center>
      <H1 class=aTitle>Windows2000 服务器端应用程序开发设计指南-事件记录</H1></DIV>
      <TABLE width="97%" align=center>
        <TBODY>
        <TR>
          <TD width=502>
            <DIV align=center>[日期:2006-10-13&nbsp;&nbsp;&nbsp;&nbsp;来源:<A 
            href="http://www.acejoy.com/" target=_blank>ACE开发者</A><SPAN 
            id=SourceLabel></SPAN>&nbsp;&nbsp;&nbsp;&nbsp;作者:Jeffrey Richter 
            Jason D. Clark<SPAN id=AuthorLabel>]</SPAN></DIV></TD>
          <TD align=right width=209>
            <DIV align=center>[字体: <INPUT title=把正文字体缩小 style="HEIGHT: 16px" onclick="fontSize('m','ArticleBody')" type=button value=小> 
<INPUT title=把正文字体扩大 style="HEIGHT: 16px" onclick="fontSize('b','ArticleBody')" type=button value=大> 
<INPUT title=转为简体中文模式 style="HEIGHT: 16px" onclick="bodytojt('ArticleBody')" type=button value=简> 
<INPUT title=转为繁体中文模式 style="HEIGHT: 16px" onclick="bodytoft('ArticleBody')" type=button value=繁> 
            <A href="javascript:fontColor('ArticleBody')"><IMG alt=字体颜色 
            src="6.3 事件记录.files/fgcolor.gif" align=absMiddle 
          border=0></A>]</DIV></TD></TR></TBODY></TABLE>
      <TABLE cellSpacing=5 cellPadding=0 width="100%" align=center border=0>
        <TBODY>
        <TR>
          <TD vAlign=top>
            <TABLE cellSpacing=0 cellPadding=10 align=left border=0>
              <TBODY>
              <TR>
                <TD></TD></TR></TBODY></TABLE>
            <DIV class=content id=ArticleBody 
            style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">
            <P class=content>
            <TABLE style="LINE-HEIGHT: 25px" border=0>
              <TBODY style="LINE-HEIGHT: 25px">
              <TR style="LINE-HEIGHT: 25px">
                <TD style="LINE-HEIGHT: 25px" align=middle><FONT 
                  style="LINE-HEIGHT: 25px" face=arial color=#000000 
                  size=2><FONT style="LINE-HEIGHT: 25px" face=arial 
                  color=#3e80d7 size=2><B 
                  style="LINE-HEIGHT: 25px">&nbsp;图6-6&nbsp;</B></FONT>MsgTableDump范例应用程序显示kernel32.dll的讯息字串</FONT></TD></TR></TBODY></TABLE>
            <CENTER></CENTER>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e72d7 
            size=4><B style="LINE-HEIGHT: 25px">AppLog范例应用程序<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>AppLog范例应用程序(「06 
            AppLog.exe」)显示于列表6-1中,它说明从一个应用程序回报事件的内容。它的原始码与资源文件存放在附赠光碟中的06-AppLog目录中。AppLog范例应用程序被实作如同一个标准的应用程序一样,但是如果控制码属于一个服务的话,它便会与回报事件的控制码相同。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>当AppLog启动时,它会开启一个本机的应用程序记录并且加入一个指示应用程序己被启动执行的项目。AppLog也会在终止前加入一个项目。在正常的情形下,为了增进执行效能并且不浪费事件记录资料库空间,您不会将这些资讯事件类型回报至事件记录中。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>一旦AppLog执行起来,您便可以在编辑控制项中键入一个Win32之错误码并按下Simulate 
            Error按钮。此按钮会使AppLog增加一个事件至系统的应用程序记录档中。当AppLog执行时,您可以依您的喜好而模拟许多Win32的错误。为了察看错误的情形,可以按下Open 
            Event Viewer按钮,以使事件检视器嵌入式管理单元在MMC中显示那些产生错误的原因。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>如果您使用事件检视器嵌入式管理单元来看那些项目,您将会看到类别与讯息识别数字与可置换的字串值(被您模拟的错误码数字)。事件检视器无法将类别与讯息识别码对应到它们的英文字串中,直到登录被适当地设定为止。若要将讯息文件模组资讯安装至登录中,可以按下Install 
            Event Message File In 
            Registry按钮。然后回去事件检视器嵌入式管理单元中察看被AppLog加入的事件。此时,您应该会看见识别号码已被转换至适当的字串中。AppLog也允许您按下Remove 
            Event Message File From 
            Registry按钮去删除登录资讯。图6-7显示了AppLog模拟一个错误的情形。</FONT></P>
            <P><BR style="LINE-HEIGHT: 25px"> </P>
            <CENTER style="LINE-HEIGHT: 25px">
            <P><INPUT id=6 style="LINE-HEIGHT: 25px" type=image height=538 
            width=659 src="6.3 事件记录.files/6-7.gif" border=0 
            &#111nclick="imgclick"></P></CENTER>
            <CENTER style="LINE-HEIGHT: 25px">
            <TABLE style="LINE-HEIGHT: 25px" border=0>
              <TBODY style="LINE-HEIGHT: 25px">
              <TR style="LINE-HEIGHT: 25px">
                <TD style="LINE-HEIGHT: 25px" align=middle><FONT 
                  style="LINE-HEIGHT: 25px" face=arial color=#000000 
                  size=2><FONT style="LINE-HEIGHT: 25px" face=arial 
                  color=#3e80d7 size=2><B 
                  style="LINE-HEIGHT: 25px">&nbsp;图6-7&nbsp;</B></FONT>AppLog范例应用程序模拟 
                  "Access is denied" (5) 
            之Win32错误码</FONT></TD></TR></TBODY></TABLE></CENTER>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">AppLog.cpp <BR>/******************************************************************** <BR>模组:AppLog.cpp <BR>通告:Copyright (c)2000 Jeffrey Richter <BR>********************************************************************/ <BR>#include "..\CmnHdr.h" // 请察看附录A <BR>#include &lt;WindowsX.h&gt; <BR>#define EVENTLOG_IMPL <BR>#include "EventLog.h" <BR>#include "Resource.h" <BR>#include "AppLogMsgs.h" // 被MC.exe产生 <BR>/////////////////////////////////////////////////////////////////////////////// <BR>CEventLog g_EventLog(TEXT("AppLog ")); <BR>/////////////////////////////////////////////////////////////////////////////// <BR>BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { <BR> chSETDLGICONS(hwnd, IDI_APPLOG); <BR> return(TRUE); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { <BR> switch (id) { <BR> case IDCANCEL: <BR>&nbsp;&nbsp;EndDialog(hwnd, id); <BR>&nbsp;&nbsp;break; <BR> case IDC_SPAWNEVENTVIEWER: <BR>&nbsp;&nbsp;// 产生事件检视器嵌入式管理单元 <BR>&nbsp;&nbsp;ShellExecute(hwnd, TEXT("Open"), TEXT("eventvwr.msc"), TEXT("/s"), <BR>&nbsp;&nbsp; NULL, SW_SHOWDEFAULT); <BR>&nbsp;&nbsp;break; <BR> case IDC_INSTALL: <BR>&nbsp;&nbsp;// 将事件记录参数文件资讯安装至登录中 <BR>&nbsp;&nbsp;chVERIFY(g_EventLog.Install( <BR>&nbsp;&nbsp; EVENTLOG_INFORMATION_TYPE | EVENTLOG_ERROR_TYPE, NULL, <BR>&nbsp;&nbsp; TEXT("Kernel32.dll"), 2, NULL)); <BR>&nbsp;&nbsp;break; <BR> case IDC_REMOVE: <BR>&nbsp;&nbsp;// 将事件记录参数文件资讯从登录中移除 <BR>&nbsp;&nbsp;chVERIFY(g_EventLog.Uninstall()); <BR>&nbsp;&nbsp;break; <BR> case IDC_SIMULATEERROR: <BR>&nbsp;&nbsp;// 回报一个Win32错误事件 <BR>&nbsp;&nbsp;TCHAR szErrorCode[10]; <BR>&nbsp;&nbsp;PCTSTR pszErrorCode = szErrorCode; <BR>&nbsp;&nbsp;GetDlgItemText(hwnd,IDC_ERRORCODE,szErrorCode, chDIMOF(szErrorCode)); <BR>&nbsp;&nbsp;chVERIFY(g_EventLog.ReportEvent(EVENTLOG_ERROR_TYPE, CAT_APPEVENT, <BR>&nbsp;&nbsp; MSG_ERROR, CEventLog::REUSER_NOTAPPLICABLE, <BR>&nbsp;&nbsp; 1, (PCTSTR*) &amp;pszErrorCode)); <BR>&nbsp;&nbsp;break; <BR> } <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>INT_PTR WINAPI Dlg_Proc(HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { <BR> switch (uMsg) { <BR> chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); <BR> chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand); <BR> } <BR> return(FALSE); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) { <BR> // 回报一个此应用程序已启动之事件 <BR> g_EventLog.ReportEvent(EVENTLOG_INFORMATION_TYPE, <BR> CAT_APPEXECSTATUS, MSG_APPSTART); <BR> DialogBox(hinstExe,MAKEINTRESOURCE(IDD_APPLOG), NULL, Dlg_Proc); <BR> // 回报一个此应用程序已停止之事件 <BR> g_EventLog.ReportEvent(EVENTLOG_INFORMATION_TYPE, <BR>&nbsp;&nbsp;CAT_APPEXECSTATUS, MSG_APPSTOP); <BR> return(0); <BR>} <BR>//////////////////////////////// End of File //////////////////////////////////</PRE></FONT></DIV>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">EventLog.h <BR>/******************************************************************** <BR>模组:EventLog.h <BR>通告:Copyright (c)2000 Jeffrey Richter <BR>********************************************************************/ <BR>#pragma once&nbsp;&nbsp; // 经由编译单元含入此标头档 <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#include "..\CmnHdr.h" /* 请参阅附录A */ <BR>/******************************************************************** <BR>加入一个讯息编译文件至Visual Studio的建构环境中,并执行以下的步骤: <BR> 1) 插入 *.mc文件至专案中 <BR> 2) 在Project Settings对话方块中选择MC文件 <BR> 3) 改变说明的内容为「Message Compiler」 <BR> 4) 加入以下二个建构命令: <BR>&nbsp;&nbsp; "mc -s -U -h $(ProjDir)-r $(ProjDir)$(InputName)" <BR>&nbsp;&nbsp; "del $(ProjDir)\$(InputName).rc" <BR> 5) 加入以下二个输出文件: <BR>&nbsp;&nbsp; "$(InputName).h" <BR>&nbsp;&nbsp; "Msg00001.bin" <BR> 6) 在原始程序代码文件中含入呼叫ReportEvent函数而产生的标头文件 <BR> 7) 由于我删除了被MC产生的 .rc文件,所以您必须使用一个值为11的资源类型以及值为 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1的资源识别码。 <BR>********************************************************************/ <BR>class CEventLog { <BR>public: <BR> CEventLog(PCTSTR pszAppName); <BR> ~CEventLog(); <BR> BOOL Install(DWORD dwTypesSupported, <BR>&nbsp;&nbsp;PCTSTR pszEventMsgFilePaths = NULL, <BR>&nbsp;&nbsp;PCTSTR pszParameterMsgFilePaths = NULL, <BR>&nbsp;&nbsp;DWORD dwCategoryCount = 0, <BR>&nbsp;&nbsp;PCTSTR pszCategoryMsgFilePaths = NULL); <BR> BOOL Uninstall(); <BR> // 记录一个事件到事件记录档中 <BR> enum REPORTEVENTUSER { REUSER_NOTAPPLICABLE, REUSER_SERVICE, REUSER_CLIENT }; <BR> BOOL ReportEvent(WORD wType, WORD wCategory, <BR>&nbsp;&nbsp;DWORD dwEventID, REPORTEVENTUSER reu = REUSER_NOTAPPLICABLE, <BR>&nbsp;&nbsp;WORD wNumStrings = 0, PCTSTR *pStrings = NULL, <BR>&nbsp;&nbsp;DWORD dwDataSize = 0, PVOID pvRawData = NULL); <BR>private: <BR> PCTSTR m_pszAppName; <BR> HANDLE m_hEventLog; <BR>}; <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#ifdef EVENTLOG_IMPL <BR>/////////////////////////////////////////////////////////////////////////////// <BR>CEventLog::CEventLog(PCTSTR pszAppName) { <BR> m_pszAppName = pszAppName; <BR> m_hEventLog = NULL; <BR>} <BR>CEventLog::~CEventLog() { <BR> if (m_hEventLog != NULL) { <BR>&nbsp;&nbsp;::DeregisterEventSource(m_hEventLog); <BR> } <BR>} <BR>////////////////////////////////////////////////////////////////////////////// <BR>BOOL CEventLog::Install(DWORD dwTypesSupported, <BR> PCTSTR pszEventMsgFilePaths, PCTSTR pszParameterMsgFilePaths, <BR> DWORD dwCategoryCount, PCTSTR pszCategoryMsgFilePaths) { <BR> // 确定至少指定了一个有效的Support Type <BR> chASSERT(0 != (dwTypesSupported &amp; <BR>&nbsp;&nbsp;(EVENTLOG_INFORMATION_TYPE | EVENTLOG_WARNING_TYPE | <BR>&nbsp;&nbsp;EVENTLOG_ERROR_TYPE))); <BR> BOOL fOk = TRUE; <BR> TCHAR szSubKey[_MAX_PATH]; <BR> wsprintf(szSubKey, <BR>&nbsp;&nbsp;TEXT("System\\CurrentControlSet\\Services\\EventLog\\Application\\%s"), <BR>&nbsp;&nbsp;m_pszAppName); <BR> // 如果应用程序没有支援任何类型(预设值) <BR> // 不要为此服务设置一个事件记录档 <BR> HKEY hkey = NULL; <BR> __try { <BR>&nbsp;&nbsp;LONG l; <BR>&nbsp;&nbsp;l = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, NULL, <BR>&nbsp;&nbsp; REG_OPTION_NON_VOLATILE, KEY_SET_VALUE,NULL, &amp;hkey, NULL); <BR>&nbsp;&nbsp;if (l != NO_ERROR)__leave; <BR>&nbsp;&nbsp;l = RegSetValueEx(hkey, TEXT("TypesSupported"), 0, REG_DWORD, <BR>&nbsp;&nbsp; (PBYTE) &amp;dwTypesSupported, sizeof(dwTypesSupported)); <BR>&nbsp;&nbsp;if (l != NO_ERROR)__leave; <BR>&nbsp;&nbsp;TCHAR szModulePathname[MAX_PATH]; <BR>&nbsp;&nbsp;GetModuleFileName(NULL, szModulePathname, chDIMOF(szModulePathname)); <BR>&nbsp;&nbsp;if (pszEventMsgFilePaths == NULL) <BR>&nbsp;&nbsp; pszEventMsgFilePaths = szModulePathname; <BR>&nbsp;&nbsp;l = RegSetValueEx(hkey, TEXT("EventMessageFile"), 0, REG_EXPAND_SZ, <BR>&nbsp;&nbsp; (PBYTE)pszEventMsgFilePaths, chSIZEOFSTRING(pszEventMsgFilePaths)); <BR>&nbsp;&nbsp;if (l != NO_ERROR)__leave; <BR>&nbsp;&nbsp;if (pszParameterMsgFilePaths == NULL) <BR>&nbsp;&nbsp; pszParameterMsgFilePaths = szModulePathname; <BR>&nbsp;&nbsp;l = RegSetValueEx(hkey, TEXT("ParameterMessageFile"), 0, REG_EXPAND_SZ, <BR>&nbsp;&nbsp; (PBYTE)pszParameterMsgFilePaths, <BR>&nbsp;&nbsp; chS, IZEOFSTRING(pszParameterMsgFilePaths)); <BR>&nbsp;&nbsp;if (l != NO_ERROR)__leave; <BR>&nbsp;&nbsp;if (dwCategoryCount &gt;0) { <BR>&nbsp;&nbsp; if (pszCategoryMsgFilePaths == NULL) <BR>&nbsp;&nbsp;&nbsp;&nbsp;pszCategoryMsgFilePaths = szModulePathname; <BR>&nbsp;&nbsp; l = RegSetValueEx(hkey, TEXT("CategoryMessageFile"), 0, <BR>&nbsp;&nbsp;&nbsp;&nbsp;REG_EXPAND_SZ, (PBYTE) pszCategoryMsgFilePaths, <BR>&nbsp;&nbsp;&nbsp;&nbsp;chSIZEOFSTRING(pszCategoryMsgFilePaths)); <BR>&nbsp;&nbsp; if (l != NO_ERROR)__leave; <BR>&nbsp;&nbsp; l = RegSetValueEx(hkey, TEXT("CategoryCount"), 0, REG_DWORD, <BR>&nbsp;&nbsp;&nbsp;&nbsp;(PBYTE) &amp;dwCategoryCount, sizeof(dwCategoryCount)); <BR>&nbsp;&nbsp; if (l != NO_ERROR)__leave; <BR>&nbsp;&nbsp;} <BR>&nbsp;&nbsp;fOk = TRUE; <BR> } <BR> __finally { <BR>&nbsp;&nbsp;if (hkey != NULL)RegCloseKey(hkey); <BR> } <BR> return(fOk); <BR>} <BR>////////////////////////////////////////////////////////////////////////////// <BR>BOOL CEventLog::Uninstall() { <BR> // 安装每一个服务的事件记录档 <BR> TCHAR szSubKey[_MAX_PATH]; <BR> wsprintf(szSubKey, <BR>&nbsp;&nbsp;TEXT("System\\CurrentControlSet\\Services\\EventLog\\Application\\%s"), <BR>&nbsp;&nbsp;m_pszAppName); <BR> return(NO_ERROR == RegDeleteKey(HKEY_LOCAL_MACHINE, szSubKey)); <BR>} <BR>////////////////////////////////////////////////////////////////////////////// <BR>BOOL CEventLog::ReportEvent(WORD wType, WORD wCategory, DWORD dwEventID, <BR> REPORTEVENTUSER reu, WORD wNumStrings, PCTSTR* pStrings, DWORD dwDataSize, <BR> PVOID pvRawData) { <BR> BOOL fOk = TRUE;&nbsp;&nbsp; // 假设成功 <BR> if (m_hEventLog == NULL) { <BR>&nbsp;&nbsp;// 这是ReportEvent第一次被呼叫与开启 <BR>&nbsp;&nbsp;m_hEventLog = ::RegisterEventSource(NULL, m_pszAppName); <BR> } <BR> if (m_hEventLog != NULL) { <BR>&nbsp;&nbsp;PSID psidUser = NULL; <BR>&nbsp;&nbsp;if (reu != REUSER_NOTAPPLICABLE) { <BR>&nbsp;&nbsp; HANDLE hToken; <BR>&nbsp;&nbsp; if (REUSER_SERVICE == reu) <BR>&nbsp;&nbsp;&nbsp;&nbsp;fOk = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &amp;h Token); <BR>&nbsp;&nbsp; else <BR>&nbsp;&nbsp;&nbsp;&nbsp;fOk = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &amp;hToken); <BR>&nbsp;&nbsp; if (fOk) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;BYTE bTokenUser[1024]; <BR>&nbsp;&nbsp;&nbsp;&nbsp;PTOKEN_USER ptuUserSID = (PTOKEN_USER) bTokenUser; <BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwReturnLength; <BR>&nbsp;&nbsp;&nbsp;&nbsp;GetTokenInformation(hToken, TokenUser, ptuUserSID, <BR>&nbsp;&nbsp;&nbsp;&nbsp; sizeof(bTokenUser), &amp;dwReturnLength); <BR>&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hToken); <BR>&nbsp;&nbsp;&nbsp;&nbsp;psidUser = ptuUserSID-&gt;User.Sid; <BR>&nbsp;&nbsp; } <BR>&nbsp;&nbsp;} <BR>&nbsp;&nbsp;fOk = fOk &amp;&amp; ::ReportEvent(m_hEventLog, wType, wCategory, dwEventID, <BR>&nbsp;&nbsp; psidUser, wNumStrings, dwDataSize, pStrings, pvRawData); <BR> } <BR> return(fOk); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#endif // SERVICECTRL_IMPL <BR>/////////////////////////////////End of File /////////////////////////////////</PRE></FONT></DIV>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">AppLogMsgs.h <BR>/************************************************************** <BR>模组:AppLogMsgs.mc <BR>通告:Copyright (c)2000 Jeffrey Richter <BR>**************************************************************/ <BR>//********************CATEGORY SECTION *********************** <BR>// 类别识别码为16位元值 <BR>// <BR>//Values是32位元值,其格式如下: <BR>// <BR>//&nbsp;&nbsp;3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 <BR>//&nbsp;&nbsp;1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 <BR>//&nbsp;&nbsp;+---+-+-+-----------------------+-------------------------------+ <BR>//&nbsp;&nbsp;|Sev|C|R|&nbsp;&nbsp; Facility&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;Code&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>//&nbsp;&nbsp;+---+-+-+-----------------------+-------------------------------+ <BR>// <BR>// 地点 <BR>// <BR>// Sev - 是重要性的控制码 <BR>// <BR>//&nbsp;&nbsp;00 - 成功 <BR>//&nbsp;&nbsp;01 - 资讯的 <BR>//&nbsp;&nbsp;10 - 警告 <BR>//&nbsp;&nbsp;11 - 错误 <BR>// <BR>//&nbsp;&nbsp;C - 是自订控制码标记 <BR>// <BR>//&nbsp;&nbsp;R - 是一个被保留的位元 <BR>// <BR>//&nbsp;&nbsp;Facility - 是设备控制码 <BR>// <BR>//&nbsp;&nbsp;Code - 是设备的状态控制码 <BR>// <BR>// <BR>// 定义设备控制码 <BR>// <BR>// <BR>// 定义重要性控制码 <BR>// <BR>// <BR>// MessageId: CAT_APPEXECSTATUS <BR>// <BR>// MessageText: <BR>// <BR>// 应用程序执行状态 <BR>// <BR>#define CAT_APPEXECSTATUS&nbsp;&nbsp;((WORD)0x20000001L) <BR>// <BR>// MessageId: CAT_APPEVENT <BR>// <BR>// MessageText: <BR>// <BR>// 应用程序事件 <BR>// <BR>#define CAT_APPEVENT ((WORD)0x20000002L) <BR>//*********************MESSAGE SECTION *********************** <BR>// 事件识别码是32位元值 <BR>// <BR>// MessageId: MSG_APPSTART <BR>// <BR>// MessageText: <BR>// <BR>// 应用程序已启动 <BR>// <BR>#define MSG_APPSTART ((DWORD)0x20000064L) <BR>// <BR>// MessageId: MSG_APPSTOP <BR>// <BR>// MessageText: <BR>// <BR>// 应用程序已停止 <BR>// <BR>#define MSG_APPSTOP ((DWORD)0x20000065L) <BR>// <BR>// MessageId: MSG_ERROR <BR>// <BR>// MessageText: <BR>// <BR>// 应用程序产生错误控制码 %1: "%%%1" <BR>// <BR>#define MSG_ERROR ((DWORD)0x20000066L) <BR>//************************END OF FILE ************************</PRE></FONT></DIV>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">AppLogMsgs.mc <BR>;/************************************************************** <BR>;模组:AppLogMsgs.mc <BR>;通告:Copyright (c)2000 Jeffrey Richter <BR>;**************************************************************/ <BR>;//********************CATEGORY SECTION *********************** <BR>;//类别识别码为16位元值 <BR>MessageIdTypedef=WORD <BR>MessageId=1 <BR>SymbolicName=CAT_APPEXECSTATUS <BR>Language=English <BR>Application execution status <BR>. <BR>MessageId=2 <BR>SymbolicName=CAT_APPEVENT <BR>Language=English <BR>Application event <BR>. <BR>;//*********************MESSAGE SECTION *********************** <BR>;// 事件识别码为32位元值 <BR>MessageIdTypedef=DWORD <BR>MessageId=100 <BR>SymbolicName=MSG_APPSTART <BR>Language=English <BR>Application started. <BR>. <BR>MessageId= <BR>SymbolicName=MSG_APPSTOP <BR>Language=English <BR>Application stopped. <BR>. <BR>MessageId= <BR>SymbolicName=MSG_ERROR <BR>Language=English <BR>Application generated error code %1:"%%%1" <BR>. <BR>;//************************END OF FILE ************************</PRE></FONT></DIV>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">AppLog.rc <BR>//Microsoft Developer Studio产生的资源指令码 <BR>// <BR>#include "Resource.h" <BR>#define APSTUDIO_READONLY_SYMBOLS <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// 从TEXTINCLUDE 2资源产生 <BR>// <BR>#include "afxres.h" <BR>///////////////////////////////////////////////////////////////////////////// <BR>#undef APSTUDIO_READONLY_SYMBOLS <BR>///////////////////////////////////////////////////////////////////////////// <BR>// English (U.S.) 资源 <BR>#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) <BR>#ifdef _WIN32 <BR>LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US <BR>#pragma code_page(1252) <BR>#endif //_WIN32 <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// 图示 <BR>// <BR>// 图示用最小的识别码值放置第一个应用程序图示,以确保在所有系统上保持一// 致。 <BR>IDI_APPLOG ICON DISCARDABLE "AppLog.ico" <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// 对话方块 <BR>// <BR>IDD_APPLOG DIALOG DISCARDABLE 15,24,280,41 <BR>STYLE DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU <BR>CAPTION "Application Log" <BR>FONT 8, "MS Sans Serif" <BR>BEGIN <BR> LTEXT "Win32 &amp;error code:",IDC_STATIC,4,6,58,8 <BR> EDITTEXT IDC_ERRORCODE,68,4,40,12,ES_AUTOHSCROLL |ES_NUMBER <BR> DEFPUSHBUTTON "&amp;Simulate error",IDC_SIMULATEERROR,112,4,53,14 <BR> PUSHBUTTON "Open Event &amp;Viewer",IDC_SPAWNEVENTVIEWER,196,4,80,14 <BR> PUSHBUTTON "&amp;Install event message file in registry",IDC_INSTALL, <BR>&nbsp;&nbsp;&nbsp;&nbsp;4,24,132,14 <BR> PUSHBUTTON "&amp;Remove event message file from registry",IDC_REMOVE, <BR>&nbsp;&nbsp;&nbsp;&nbsp;144,24,132,14 <BR>END <BR>#ifdef APSTUDIO_INVOKED <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// TEXTINCLUDE <BR>// <BR>1 TEXTINCLUDE DISCARDABLE <BR>BEGIN <BR> "Resource.h \0" <BR>END <BR>2 TEXTINCLUDE DISCARDABLE <BR>BEGIN <BR> "#include ""afxres.h""\r\n" <BR> "\0" <BR>END <BR>3 TEXTINCLUDE DISCARDABLE <BR>BEGIN <BR> "\r\n" <BR> "\0" <BR>END <BR>#endif&nbsp;&nbsp; // APSTUDIO_INVOKED <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// DESIGNINFO <BR>// <BR>#ifdef APSTUDIO_INVOKED <BR>GUIDELINES DESIGNINFO DISCARDABLE <BR>BEGIN <BR> IDD_APPLOG,DIALOG <BR> BEGIN <BR>&nbsp;&nbsp;RIGHTMARGIN, 276 <BR>&nbsp;&nbsp;BOTTOMMARGIN, 37 <BR> END <BR>END <BR>#endif&nbsp;&nbsp; // APSTUDIO_INVOKED <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// 11 <BR>// <BR>LANGUAGE 0x9,0x1 <BR>1 11 MSG00001.bin <BR>#endif&nbsp;&nbsp; // English (U.S.) 资源 <BR>///////////////////////////////////////////////////////////////////////////// <BR>#ifndef APSTUDIO_INVOKED <BR>///////////////////////////////////////////////////////////////////////////// <BR>// <BR>// 从TEXTINCLUDE 3资源产生 <BR>// <BR>///////////////////////////////////////////////////////////////////////////// <BR>#endif&nbsp;&nbsp; // 非APSTUDIO_INVOKED</PRE></FONT></DIV>
            <CENTER style="LINE-HEIGHT: 25px">
            <TABLE style="LINE-HEIGHT: 25px" border=0>
              <TBODY style="LINE-HEIGHT: 25px">
              <TR style="LINE-HEIGHT: 25px">
                <TD style="LINE-HEIGHT: 25px" align=middle><FONT 
                  style="LINE-HEIGHT: 25px" face=arial color=#000000 
                  size=2><FONT style="LINE-HEIGHT: 25px" face=arial 
                  color=#3e80d7 size=2><B 
                  style="LINE-HEIGHT: 25px">&nbsp;列表6-1&nbsp;</B></FONT>AppLog范例应用程序</FONT></TD></TR></TBODY></TABLE></CENTER></A><A 
            style="LINE-HEIGHT: 25px" name=206004>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7 
            size=5><B style="LINE-HEIGHT: 25px">读取事件记录<BR 
            style="LINE-HEIGHT: 25px"> </B></FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>Windows之事件检视器嵌入式管理单元通常已可满足大部份的事件读取需求。然而,Windows提供了允许您的应用程序去存取事件记录档的函数。有很大的可能会使用到这样的特性—例如,您可以编写一个应用程序,当它侦测到某些识别码被加入事件记录的事件进入时,便传送一个电子邮件。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>为了要读取已启动的事件记录,您的应用程序必须先透过呼叫OpenEventLog而取回一个到记录的handle:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">HANDLE OpenEventLog( <BR> PCTSTR pszUNCServerName, <BR> PCTSTR pszLogName);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>pszUNCServerName参数确认了含有您想要存取之事件记录的机器。pszLogName参数则在服务器上识别特定的记录。一旦您拥有一个到记录档之有效handle,即表示您已准备去读取事件。通常,当您完成了对记录档的存取时。您应该透过呼叫CloseEventLog来关闭该handle:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL CloseEventLog(HANDLE hEventLog);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>读取事件需要一个对ReadEventLog的呼叫:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL ReadEventLog( <BR> HANDLE hEventLog, <BR> DWORD dwReadFlags, <BR> DWORD dwRecordOffset, <BR> PVOID pvBuffer, <BR> DWORD nNumberOfBytesToRead, <BR> PDWORD pnBytesRead, <BR> PDWORD pnMinNumberOfBytesNeeded);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>hEventLog参数是从OpenEventLog回传的handle。dwReadFlags参数则确认您将连续地读取记录或是从一个特定的记录开始读取。表6-5列出dwReadFlags可能的标记。一个常见的之被传递的值为EVENTLOG_FORWARDS_READ 
            | EVENTLOG_SEQUENTIAL_READ。</FONT></P>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?