【问题标题】:Where can I find a good example of ReportEvent function usage?我在哪里可以找到 ReportEvent 函数使用的好例子?
【发布时间】:2009-08-17 22:14:26
【问题描述】:

与大多数“旧版”MSDN 页面一样,ReportEvent 页面的信息太少,我无法理解它。我试过搜索,但找不到一个好的、干净、简单的函数用法示例。谁能推荐一个?

【问题讨论】:

    标签: winapi advapi32


    【解决方案1】:

    我最终使用了这个:

    HANDLE eventLog;
    WORD type;
    const char* msg;
    
    // ... snip ...
    
    ReportEvent(eventLog, type, 0, 1, NULL, 1, 0, &LPCTSTR(msg), NULL);
    

    似乎工作得很好。

    【讨论】:

    • 这个解决方案的问题是它记录混乱(参见:Windows Vista 上的“无法找到来自源 XYZ.exe 的事件 ID 1 的描述”)。
    【解决方案2】:

    嗯,这似乎是一个非常古老的线程,在这里寻找报告事件的一个很好的例子......但发现你没有收到任何回复......并且可能已经找到了解决方案。

    您看到“找不到事件 ID”的原因是 EventViewer 无法加载/查找要为事件 ID 显示的文本资源。抱歉,如果最后一行听起来很怪异……但这是我对 EventLog 的理解:

    -EventLogging有两个方面

    1. 向 EventLog 注册(或以其他方式创建 EventSource)
    2. 记录或写入事件日志
    3. 查看或读取日志

    当您在事件日志中注册时,您只需指定一个 eventSource(标识该日志的任何名称)+ EventMessageFile、Category File 和 SupportedEventTypes。这里 EventMessageFile 指向一个 DLL/EXE,其中包含您的消息描述/资源。

    当您记录一个事件时,您只需使用一些数据(例如 EventID、Category ID 和 EventData)来记录它。但是,当您使用任何 EventViewer(或 Windows eventVwr.exe)查看它时,查看器会读取您的事件,查找与您的 eventSource(由 EventMessageFile 指向)关联的 DLL/EXE,并从该 DLL/EXE 的资源部分呈现说明.

    这个 DLL 只是一个使用 MessageCompiler 编译的简单资源文件,并包含一个“MessageTable”。这样做是为了提供特定于文化的事件日志记录

    这就是原因,当您从 EventViewer 将日志导出为 XML/TXT 等时,它会询问您是要“带显示信息”还是“不带显示信息”保存它,以便您可以在没有 EventMessageFile 的计算机。

    JFYI reg 条目位于:

    HKLM\CurrentControlSet\System\Services\EventLog\Application
    

    一个问题:如果您想知道 .Net 是如何做到的...,它只是通过提供一个名为 EventLogMessage.dll 的默认 EventMessageFile 来做到这一点(在 %SYSTEMROOT%\Microsoft.Net\Framework\vXXXX\ 下找到)

    【讨论】:

    • 如果您不需要特定于语言/文化的消息,您可以生成一个消息 DLL,它只包含一个映射到资源“%1”的 ID(例如 GENERIC_MESSAGE)。然后,您为您的应用程序注册此 DLL,并简单地将要在事件查看器中显示的字符串作为此消息的第一个参数传递。此方法在codeproject.com/Articles/3995/… 中进行了描述,但请注意在调用“mc”时使用“-c”标志以使示例正常工作!
    【解决方案3】:

    我记得正确设置很痛苦 - 您需要使用 Message Compiler 向您的应用程序添加消息 - 如果您跳过此操作,您将不会看到有用的消息,只有错误代码。以Creating a Windows NT Service by Using ATL 为例

    【讨论】:

      【解决方案4】:

      示例 Windows 服务 C++,是一个向事件日志报告的 Windows 服务,您可以从https://code.msdn.microsoft.com/windowsapps/CppWindowsService-cacf4948 获取代码 特别是,以下函数(引用自 ServiceBase.cpp)可以做到这一点

      //
      //   FUNCTION: CServiceBase::WriteEventLogEntry(PWSTR, WORD)
      //
      //   PURPOSE: Log a message to the Application event log.
      //
      //   PARAMETERS:
      //   * pszMessage - string message to be logged.
      //   * wType - the type of event to be logged. The parameter can be one of 
      //     the following values.
      //
      //     EVENTLOG_SUCCESS
      //     EVENTLOG_AUDIT_FAILURE
      //     EVENTLOG_AUDIT_SUCCESS
      //     EVENTLOG_ERROR_TYPE
      //     EVENTLOG_INFORMATION_TYPE
      //     EVENTLOG_WARNING_TYPE
      //
      void CServiceBase::WriteEventLogEntry(PWSTR pszMessage, WORD wType)
      {
          HANDLE hEventSource = NULL;
          LPCWSTR lpszStrings[2] = { NULL, NULL };
      
          hEventSource = RegisterEventSource(NULL, m_name);
          if (hEventSource)
          {
              lpszStrings[0] = m_name;
              lpszStrings[1] = pszMessage;
      
              ReportEvent(hEventSource,  // Event log handle
                  wType,                 // Event type
                  0,                     // Event category
                  0,                     // Event identifier
                  NULL,                  // No security identifier
                  2,                     // Size of lpszStrings array
                  0,                     // No binary data
                  lpszStrings,           // Array of strings
                  NULL                   // No binary data
                  );
      
              DeregisterEventSource(hEventSource);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-14
        • 2011-12-31
        • 2010-11-16
        相关资源
        最近更新 更多