【问题标题】:Write in Windows-Eventlog with Delphi Event-ID not found在 Windows-Eventlog 中写入 Delphi Event-ID 未找到
【发布时间】:2017-11-08 13:38:36
【问题描述】:

我正在用 Delphi 为 Windows 编写一个服务应用程序。在某些事件中,我将消息写入 Windows 事件日志。这可行,但每个日志条目中都有以下文本:

无法找到来自源 yyyyy 的事件 ID xxx 的描述...

我不想要这个。

我做了什么:

  1. 使用此内容生成 ResouceEventlog.mc:

    SeverityNames=(成功=0x0:STATUS_SEVERITY_SUCCESS 信息=0x1:STATUS_SEVERITY_INFORMATIONAL 警告=0x2:STATUS_SEVERITY_WARNING 错误=0x3:STATUS_SEVERITY_ERROR ) FacilityNames=(系统=0x0:FACILITY_SYSTEM 运行时=0x2:FACILITY_RUNTIME 存根=0x3:FACILITY_STUBS IO=0x4:FACILITY_IO_ERROR_CODE ) 语言名称=(德语=0x407:MSG00407) MessageIdTypedef=WORD 消息 ID=0x1 符号名称=CAT_ALL 语言=德语 全部 . 消息 ID=0x2 符号名=CAT_CALL 语言=德语 安鲁夫 . 消息 ID=0x3 符号名=CAT_LIC 语言=德语 利岑信息 . 消息 ID=0x4 符号名称=CAT_INFO 语言=德语 信息 . 消息 ID=0x5 符号名=CAT_ERR 语言=德语 费勒 . MessageIdTypedef=DWORD 消息 ID=0x1000 符号名=LIC_INFO 语言=德语 利岑信息 . 消息 ID=0x1001 符号名=LIC_EXP 语言=德语 利岑信息 . 消息 ID=0x2000 符号名称=CALL_SiG 语言=德语 信号传递 . 消息 ID=0x2001 符号名=CALL_DBL 语言=德语 Anruf bereits erfasst . 消息 ID=0x2002 符号名=CALL_CAPI 语言=德语 Anruf 一个 CAPI . 消息 ID=0x2003 符号名=CALL_PROCESS 语言=德语 Anruf verarbeiten . 消息 ID=0x3000 符号名=ERR_CAPI 语言=德语 卡皮费勒 . 消息 ID=0x3001 符号名=ERR_PATH 语言=德语 Speicherpfad kann nicht erstellt weren . 消息 ID=0x3002 符号名=ERR_NOCAPI 语言=德语 Keine CAPI gefunden . 消息 ID=0x3003 符号名=ERR_UDP 语言=德语 UDP_Empfangs_Port ist 0 .
  2. mc.exe编译ResourceEventlog.mc

  3. RecourceEventLog.rcbrcc32.exe编译成ResourceEventlog.res

  4. {$R RecourceEventlog.res}添加到我的服务应用程序的主单元

  5. AfterInstall 事件中,我创建了一些注册表项:

    Windows 注册表编辑器版本 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Anrufmonitor] "EventMessageFile"="C:\\AM\\AMService.exe" "CategoryMessageFile"="C:\\AM\\AMService.exe" “类别计数”=dword:00000005 “支持的类型”=dword:00000007
  6. 在我的服务应用程序中,我定义了一些常量并使用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”文本。

【问题讨论】:

  • 在添加注册表项后您是否重新启动了事件查看器?
  • 没有。我已经测试了你的想法,但我得到了相同的结果。
  • 我希望事件日志使用 DWORD 从资源中获取 MessageID。我在 mc-file 中也定义为 DWORD 单位。但是随后eventlog在evententry中显示的总是整数。所以我不知道这是否正确,但我认为是的。
  • This 是关于第 5 点中的 ID。

标签: windows delphi event-log


【解决方案1】:

.mc 文件中的所有消息均未指定 SeverityFacility。默认SeveritySuccess,它在您的SeverityName 列表中,但默认FacilityApplication (0xFFF),它不在您的FacilityNames 列表中。

消息的SeverityFacility 编号作为最终资源ID 编号的一部分包含在编译的消息资源中。这是必须在其dwEventID 参数中传递给ReportEvent()(由TService.LogMessage() 包装)的数字,以便它可以找到正确的资源字符串。该参数的确切格式记录在 MSDN 上:

Event Identifiers

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|设施 |代码 | +---+-+-+------------+------ --------------+ 严重性 严重性。严重性定义如下: 00 - 成功 01 - 信息 10 - 警告 11 - 错误 C 客户位。该位定义如下: 0 - 系统代码 1 - 客户代码 R 保留位。 设施 设施代码。该值可以是 FACILITY_NULL。 代码 设施的状态代码。

这也包含在 MSDN 支持中:

HOWTO: Troubleshooting the "Event Message Not Found" Message

  1. 确保将正确的 ID 传递给 ReportEvent 函数。

许多人认为在 .mc 文件中找到的文字 ID 号是正确的 ID。情况并非如此,因为消息编译器将 ID 号按位或运算到 LOWORD 中,并将严重性和设施位按位或运算到 HIWORD 中。应用程序应始终使用从消息编译器输出的头文件中的符号名称。

验证 .mc 文件中的 MessageIdTypedef= 语句。一些示例 .mc 文件显示了如何将 MessageIDTypedef 定义为 WORD 用于类别 ID。但是,这会导致事件 ID 丢失 HIWORD。要更正此问题,请仅定义一次 MessageIdTypedef= 并将其设置为 DWORD。

还要确保 MC -c 命令行始终用于消息资源和头文件。 -c 开关在消息 ID 的 HIWORD 中打开一点。

mc.exe-c 开关使其“在所有消息 ID 中设置客户位(位 28)。

但是,您的 Delphi 常量不考虑这种格式。

例如,您的.mc 文件定义了CALL_PROCESS0x2003MessageID(上面的Code)并且没有SeverityFacility,所以Success=0x0Application=0xFFF 是分别使用。因此,CALL_PROCESS 的实际 EventID 是 0x2FFF2003(您可以通过使用任何资源查看器/编辑器工具查看已编译的消息资源来验证这一点)。

但是,您的 Delphi 代码将 CALL_PROCESS 定义为 $00002003,这不是您需要传递给 LogMessage() 的正确数字!

这同样适用于您的所有其他消息 EventID(LIC_INFOERR_UDP)。

消息的category identifierMessageID 按原样使用,因此您的Delphi 代码中的那些类别常量(CAT_ALLCAT_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 文件以为每条消息明确指定正确的 SeverityFacility 值,也请确保您还在 Delphi 常量中考虑了 Customer 位。

例如,如果您将每条消息的 Facility 设置为 0x0,则正确的 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   =$20003000;
  ERR_PATH     :DWORD   =$20003001;
  ERR_NOCAPI   :DWORD   =$20003002;
  ERR_UDP      :DWORD   =$20003003;

然后,如果您在错误消息中将 Severity 设置为 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;

因此,正确定义 EventID 常量对于ReportEvent() 是否可以在消息资源中找到它们有很大的不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多