我正在用Delphi编写Windows的Service应用程序。在某些事件中,我将消息写入Windows EventLog。这样可行,但每个日志条目中都有以下文本:
无法找到源yyyyy的事件ID xxx的描述......
我不想要这个。
我做了什么:
使用以下内容生成ResouceEventlog.mc:
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=(German=0x407:MSG00407) MessageIdTypedef=WORD MessageID=0x1 Symbolicname=CAT_ALL Language=German Allgemein . MessageID=0x2 Symbolicname=CAT_CALL Language=German Anruf . MessageID=0x3 Symbolicname=CAT_LIC Language=German Lizenzinformation . MessageID=0x4 Symbolicname=CAT_INFO Language=German Informationen . MessageID=0x5 Symbolicname=CAT_ERR Language=German Fehler . MessageIdTypedef=DWORD MessageID=0x1000 Symbolicname=LIC_INFO Language=German Lizenzinformationen . MessageID=0x1001 Symbolicname=LIC_EXP Language=German Lizenzinformationen . MessageID=0x2000 Symbolicname=CALL_SiG Language=German Anruf signalisieren . MessageID=0x2001 Symbolicname=CALL_DBL Language=German Anruf bereits erfasst . MessageID=0x2002 Symbolicname=CALL_CAPI Language=German Anruf an CAPI . MessageID=0x2003 Symbolicname=CALL_PROCESS Language=German Anruf verarbeiten . MessageID=0x3000 Symbolicname=ERR_CAPI Language=German Capi Fehler . MessageID=0x3001 Symbolicname=ERR_PATH Language=German Speicherpfad kann nicht erstellt weren . MessageID=0x3002 Symbolicname=ERR_NOCAPI Language=German Keine CAPI gefunden . MessageID=0x3003 Symbolicname=ERR_UDP Language=German UDP_Empfangs_Port ist 0 .
使用ResourceEventlog.mc
mc.exe
将RecourceEventLog.rc
与brcc32.exe
编译为ResourceEventlog.res
将{$R RecourceEventlog.res}
添加到我的服务应用程序的主单元
在AfterInstall
事件中,我创建了一些注册表项:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Anrufmonitor] "EventMessageFile"="C:\\AM\\AMService.exe" "CategoryMessageFile"="C:\\AM\\AMService.exe" "CategoryCount"=dword:00000005 "TypesSupported"=dword:00000007
在我的服务应用程序中,我定义了一些常量并使用TService.LogEvent()
将消息写入事件日志:
const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$00001000;
LIC_EXP :DWORD =$00001001;
CALL_SIG :DWORD =$00002000;
CALL_DBL :DWORD =$00002001;
CALL_CAPI :DWORD =$00002002;
CALL_PROCESS :DWORD =$00002003;
ERR_CAPI :DWORD =$00003000;
ERR_PATH :DWORD =$00003001;
ERR_NOCAPI :DWORD =$00003002;
ERR_UDP :DWORD =$00003003;
...
LogMessage('test an eventlog-entry', EVENTLOG_INFORMATION_TYPE, CAT_CALL, CALL_PROCESS);
事件日志条目已成功创建,但无法找到"事件ID"文字仍然出现。
答案 0 :(得分:2)
.mc
文件中的所有邮件均未指定Severity
或Facility
。默认Severity
为Success
,位于SeverityName
列表中,但默认Facility
为Application
(0xFFF
),但不是在您的FacilityNames
列表中。
消息的Severity
和Facility
号码作为存储在已编译消息资源中的最终资源ID号的一部分包含在内。这是必须在TService.LogMessage()
参数中传递给ReportEvent()
(由dwEventID
包装)的数字,以便它可以找到正确的资源字符串。 MSDN上记录了该参数的确切格式:
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 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 +---+-+-+-----------------------+-------------------------------+ |Sev|C|R| Facility | Code | +---+-+-+-----------------------+-------------------------------+ Sev Severity. The severity is defined as follows: 00 - Success 01 - Informational 10 - Warning 11 - Error C Customer bit. This bit is defined as follows: 0 - System code 1 - Customer code R Reserved bit. Facility Facility code. This value can be FACILITY_NULL. Code Status code for the facility.
这也包含在MSDN支持中:
HOWTO: Troubleshooting the "Event Message Not Found" Message
- 确保将正确的ID传递给ReportEvent函数。
醇>许多人认为.mc文件中的文字ID号是正确的ID。这不是那么,因为消息编译器将ID编号按位OR运算为LOWORD,并将严重性和设施位按位OR运算为HIWORD。应用程序应始终使用从消息编译器输出的头文件中的符号名称。
验证.mc文件中的MessageIdTypedef =语句。一些示例.mc文件显示如何为类别ID定义MessageIDTypedef为WORD。但是,这会导致事件ID松开HIWORD。要解决此问题,请仅定义MessageIdTypedef =一次并将其设置为DWORD。
还要确保MC -c命令行始终用于消息资源和头文件。 -c开关在消息ID的HIWORD中打开一个位。
mc.exe
的-c
开关导致" 在所有消息ID中设置客户位(位28)。"
但是,您的Delphi常量并不考虑这种格式。
例如,您的.mc
文件定义CALL_PROCESS
MessageID
(Code
以上)0x2003
且Severity
或{ {1}},分别使用Facility
和Success=0x0
。因此,Application=0xFFF
的实际EventID是CALL_PROCESS
(您可以通过使用任何资源查看器/编辑器工具查看已编译的消息资源来验证这一点。)
但是,您的Delphi代码将0x2FFF2003
定义为CALL_PROCESS
,这不是您需要传递给$00002003
的正确数字!
这同样适用于您的所有其他消息EventID(LogMessage()
到LIC_INFO
)。
邮件category identifier的ERR_UDP
按原样使用,因此您的Delphi代码(MessageID
到CAT_ALL
)中的类别常量都很好
请改为尝试:
CAT_ERR
即使您修复了const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$2FFF1000;
LIC_EXP :DWORD =$2FFF1001;
CALL_SIG :DWORD =$2FFF2000;
CALL_DBL :DWORD =$2FFF2001;
CALL_CAPI :DWORD =$2FFF2002;
CALL_PROCESS :DWORD =$2FFF2003;
ERR_CAPI :DWORD =$2FFF3000;
ERR_PATH :DWORD =$2FFF3001;
ERR_NOCAPI :DWORD =$2FFF3002;
ERR_UDP :DWORD =$2FFF3003;
文件以明确指定每封邮件的正确.mc
和Severity
值,也请确保您还考虑Delphi常量中的Customer位。
例如,如果您将每条消息的Facility
设置为0x0,则正确的EventID将如下所示:
Facility
然后,如果您在错误消息上将const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$20001000;
LIC_EXP :DWORD =$20001001;
CALL_SIG :DWORD =$20002000;
CALL_DBL :DWORD =$20002001;
CALL_CAPI :DWORD =$20002002;
CALL_PROCESS :DWORD =$20002003;
ERR_CAPI :DWORD =$20003000;
ERR_PATH :DWORD =$20003001;
ERR_NOCAPI :DWORD =$20003002;
ERR_UDP :DWORD =$20003003;
设置为Severity
,则正确的EventID将如下所示:
Error
因此,正确定义EventID常量会使const
CAT_ALL :WORD =$1;
CAT_CALL :WORD =$2;
CAT_LIC :WORD =$3;
CAT_INFO :WORD =$4;
CAT_ERR :WORD =$5;
LIC_INFO :DWORD =$20001000;
LIC_EXP :DWORD =$20001001;
CALL_SIG :DWORD =$20002000;
CALL_DBL :DWORD =$20002001;
CALL_CAPI :DWORD =$20002002;
CALL_PROCESS :DWORD =$20002003;
ERR_CAPI :DWORD =$E0003000;
ERR_PATH :DWORD =$E0003001;
ERR_NOCAPI :DWORD =$E0003002;
ERR_UDP :DWORD =$E0003003;
是否可以在消息资源中找到它们有很大的不同。