Windows:ReportEvent 函数

Windows: ReportEvent function

提问人:Sergey Shandar 提问时间:3/23/2011 最后编辑:Sergey Shandar 更新时间:7/15/2017 访问量:4845

问:

据我了解,ReportEvent 函数需要通过注册表关联的消息文本文件才能接收格式正确的消息。是否有任何常见的事件 ID 或任何简单的方法来报告没有关联的消息文本文件的事件?

或者可能是,是否有特殊的通用事件源可以在我的应用程序中使用?像 RegisterEventSource(NULL, “Application”) 这样的东西?

Windows WinAPI 事件日志 消息格式

评论


答:

1赞 David Heffernan 3/23/2011 #1

不,你只需要遵循规则并定义你的消息文本文件,将它们构建到资源中,将它们链接到你的应用程序等。

MSDN 提供的示例将引导您完成需要执行的所有操作。

评论

0赞 Sergey Shandar 3/25/2011
我可以使用其他人的消息文件而不链接我的应用程序吗?这里的主要问题是链接。
0赞 David Heffernan 3/25/2011
请按照说明操作。是什么阻止了你这样做?
1赞 Sergey Shandar 3/25/2011
我不想让我的应用程序注册一些东西,我不想要任何类型的安装。我想从另一台计算机复制它,它必须工作。
2赞 David Heffernan 3/25/2011
如果不注册,则事件最终会显示在应用程序日志中。文档指出:“如果找不到源名称,事件日志记录服务将使用应用程序日志。自己试试吧。
1赞 f0ster 7/18/2011 #2

试试这个,它以前对我有用。.

http://www.codeproject.com/KB/system/xeventlog.aspx

3赞 Ian Boyd 7/15/2017 #3

不必在 HKLM 中注册您的消息。(这是一件好事,因为如果您不是管理员,则无法注册邮件)。

但这并不能阻止你将事件写入 Windows 应用程序事件日志。唯一的缺点是,从Windows Vista开始,您只会得到一些丑陋的文本。

HRESULT LogToEventLog(String Source, String EventText, int EventType, DWORD EventID)
{
   /*
      EventType is one of:
         EVENTLOG_ERROR_TYPE       = $0001;
         EVENTLOG_WARNING_TYPE     = $0002;
         EVENTLOG_INFORMATION_TYPE = $0004;
         EVENTLOG_AUDIT_SUCCESS    = $0008;
         EVENTLOG_AUDIT_FAILURE    = $0010;

      Source is your name for your app or feature, e.g.:
         "My Cool App"
         "Outlook"    
         "ESENT"
         "Chrome"
   */

   HANDLE h = RegisterEventSource(null, Source); //null --> local computer
   if (h == 0) 
      return HResultFromWin32(GetLastError);
   try
   {       
      PChar[1] ss;
      ss[0] = PChar(EventText);

      if (!ReportEvent(
            h,         // event log handle
            EventType, // event type
            0,         // category zero
            EventID,   // event identifier
            null,      // no user security identifier
            1,         // one substitution string
            0,         // no data
            @ss,       // pointer to string array
            null       // pointer to data
      ))
      {
         return HResultFromWin32(GetLastError);
      }
   }
   finally
   {
      DeregisterEventSource(h);
   }
   return S_OK;
}

因此,现在您可以将事件记录到应用程序事件日志中:

LogToEventLog("Stackoverflow", "Question 5399066 was answered by Ian Boyd", 
      EVENTLOG_INFORMATION_TYPE, 0x45);

窃取他人的注册

不幸的是,从 Windows Vista 开始,Windows 会发出丑陋的抱怨,说您没有事先注册事件:

源 Stackoverflow 中的事件 ID 69 的描述不能是 发现。引发此事件的组件未安装在 您的本地计算机或安装已损坏。您可以安装 或修复本地计算机上的组件。

如果事件源自另一台计算机,则显示信息 必须与事件一起保存。

该活动包含以下信息:

问题5399066由伊恩·博伊德(Ian Boyd)回答

但你不必忍受它。仅仅因为您没有在 HKLM 中注册消息源文件,并不意味着其他人都没有注册。

例如,请注意事件日志中来自 Outlook 源的消息:

  • 来源Outlook
  • 事件 ID:0x40000020
  • 事件数据D:\win32app\Exchange\Outlook2003.pst
  • 留言内容The store D:\win32app\Exchange\Outlook2003.pst has detected a catalog checkpoint.

您可以在以下位置查看 Outlook 的注册信息:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Outlook

并查看:

MessageEventFile: REG_SZ = "D:\Programs\MICROS~4\Office14\1033\MAPIR.DLL"

如果查看 MAPIR.dll 二进制文件的资源,将看到其消息表

1 MESSAGETABLE
{
0x12,       "Connection stats for server (%1).  Rpcs Attempted (%2), Rpcs Succeeded (%3), Rpcs Failed (%4), Rpcs Canceled (%5), Rpc UI shown (%6), Avg request time (%7) ms, Min request time (%8) ms, Max request time (%9) ms.\r\n"
0x14,       "Cancelable RPC started.\r\n"
0x15,       "Cancelable RPC shutdown.\r\n"
0x40000010,     "Cancelable RPC dialog shown for server (%1), total wait time was (%2) ms, result was (%3).\r\n"
0x40000011,     "User canceled request against server (%1) after waiting (%2) ms.\r\n"
0x40000013,     "Rpc call (%1) on transport (%2) to server (%3) failed with error code (%4) after waiting (%5) ms; eeInfo (%6).\r\n"
0x40000016,     "There was a problem reading one or more of your reminders. Some reminders may not appear.\r\n"
0x40000017,     "Unable to update public free/busy data.\r\n"
0x4000001A,     "%1\r\n"
0x4000001B,     "%1\r\n"
0x4000001D,     "The store %1 is being re-pushed to the indexer for the following reason: %2.\r\n"
0x4000001E,     "Starting reconciliation for the store %1 for the following reason: %2.\r\n"
0x4000001F,     "The store %1 has detected a catalog rebuild.\r\n"
0x40000020,     "The store %1 has detected a catalog checkpoint.\r\n"
...
}

您可以看到 eventid 0x40000020与格式字符串相关联:

“存储 %1 检测到目录检查点。\r\n”

您可以劫持 Outlook 的注册:

LogToEventLog("Outlook", "Your mom", EVENTLOG_INFORMATION_TYPE, $40000020);

您将事件添加到事件日志中,而不会出现所有丑陋的警告:

enter image description here