VC 中的日志事件
在 VC 中使用 EventLog
引言
有时,我们需要记录代码的一些行为。当程序出错时,我们可以快速了解原因,因此有人会编写一个记录器,但我们有更好的选择,即 Windows 事件日志服务。
背景
熟悉 Windows DLL,并了解如何创建 DLL 项目。
Using the Code
首先,我们需要一个仅包含资源的 DLL 文件。我们可以使用 VC 2005 创建一个 DLL 项目,入口点(EventMsg.cpp)如下
#include "stdafx.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
我们应该包含一个 MC 文件,该文件定义了消息 ID、消息符号名等。我编写了一个仅用于演示的文件,mymsg.mc。
MessageIdTypedef=DWORD
SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
Warning=0x2:STATUS_SEVERITY_WARNING
Error=0x3:STATUS_SEVERITY_ERROR
)
FacilityNames=(System=0x0:FACILITY_SYSTEM
Runtime=0x2:FACILITY_RUNTIME
Stubs=0x3:FACILITY_STUBS
Io=0x4:FACILITY_IO_ERROR_CODE
)
LanguageNames=(English=0x409:MSG00409)
MessageId=0x1
Severity=Error
Facility=Runtime
SymbolicName=MSG_BAD_ERROR1
Language=English
error one.//will appear in the event description
.
MessageId=0x2
Severity=Warning
Facility=Io
SymbolicName=MSG_BAD_ERROR2
Language=English
error two.//will appear in the event description
.
MessageId=0x3
Severity=Success
Facility=System
SymbolicName=MSG_BAD_ERROR3
Language=English
error three.//will appear in the event description.
现在,我们应该首先使用 cl.exe 编译它。
cl -fo EventMsg.cpp
也许 cl
会抱怨一些事情,但别担心,无论如何我们都得到了 EventMsg.obj
,这就足够了。然后我们编译 mymsg.mc。
mc mymsg.mc
我们得到了 mymsg.rc 和 mymsg.h(此文件将由客户端使用)。
rc -r -fo mymsg.res mymsg.rc
最后,我们将 mymsg.res 与 EventMsg.obj 链接。
link -dll -out:mymsg.dll EventMsg.obj mymsg.res
我们现在已经获得了仅包含资源的 DLL 文件,即 mymsg.dll 文件。然后我们注册它。我只是手动将其写入注册表,您可以完善此行为。:)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyApp
在 MyApp 项下创建两个键,一个是 EventMessageFile
(STRING
)。
%SystemRoot%\System32\mymsg.dll
另一个是 TypeSupported
(DWORD
)。
0x0000001f
其次,我们应该编写一个客户端来使用 EventLog
//
#include "stdafx.h"
#include "Windows.h"
#include "mymsg.h"
#include "stdlib.h"
void ReportOneEvent(LPCSTR szMsg)
{
HANDLE h = RegisterEventSource(NULL, "MyApp");
if(h == NULL)
printf("register source error");
if (!ReportEvent(h,
EVENTLOG_ERROR_TYPE,
6,
MSG_BAD_ERROR3, //so the event description is "error three"
NULL,
1,
strlen(szMsg),
&szMsg, //this szMsg("event test") is the event data
(void*)szMsg))
printf("event report error");
DeregisterEventSource(h);
}
int _tmain(int argc, _TCHAR* argv[])
{
ReportOneEvent("event test");
return 0;
}
您可以使用系统工具->事件查看器来检查它。
关注点
我们可以深入研究 ReportEvent
,例如:第三个参数 WORD
wCategory,我们可以通过设置该参数在事件查看器中查看不同的类别。
历史
- 2009/01/17 版本 1.0.0.2