将事件写入事件查看器

Posted

技术标签:

【中文标题】将事件写入事件查看器【英文标题】:Write an Event to the Event viewer 【发布时间】:2011-12-19 09:20:46 【问题描述】:

我在 C# 中找到了一个如何将新事件添加到事件查看器的示例。 但是,我需要一个用 C++(不是 .NET)编写的示例,该示例在“应用程序”部分下为事件查看器创建新事件。

【问题讨论】:

这是一个更简单、直接的解决方案,可以让基本的事件日志记录正常工作:***.com/questions/37035958/… 【参考方案1】:

您可以从 WINAPI 中使用这三个函数:

RegisterEventSource ReportEvent DeregisterEventSource

这里是一个快速示例,说明如何使用它们并在事件日志中正确显示消息(为简洁起见,错误处理大多被忽略)。

从以下Event_log.mc 文件中创建一个包含消息信息的资源:

;#ifndef _EXAMPLE_EVENT_LOG_MESSAGE_FILE_H_
;#define _EXAMPLE_EVENT_LOG_MESSAGE_FILE_H_

MessageIdTypeDef=DWORD


SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
               Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
               Warning=0x2:STATUS_SEVERITY_WARNING
               Error=0x3:STATUS_SEVERITY_ERROR
               )

LanguageNames=(EnglishUS=0x401:MSG00401
               Dutch=0x113:MSG00113
               Neutral=0x0000:MSG00000
               )

MessageId=0x0   SymbolicName=MSG_INFO_1
Severity=Informational
Facility=Application
Language=Neutral
%1
.

MessageId=0x1   SymbolicName=MSG_WARNING_1
Severity=Warning
Facility=Application
Language=Neutral
%1
.

MessageId=0x2   SymbolicName=MSG_ERROR_1
Severity=Error
Facility=Application
Language=Neutral
%1
.

MessageId=0x3   SymbolicName=MSG_SUCCESS_1
Severity=Success
Facility=Application
Language=Neutral
%1
.


;#endif

为了构建.mc 文件和.res 资源文件,我执行了以下操作:

mc.exe -A -b -c -h . -r resources Event_log.mc
rc.exe -foresources/Event_log.res resources/Event_log.rc

这将在当前目录中创建一个名为 Event_log.h 的头文件和一个 resources 目录,其中包含一个名为 Event_log.res 的文件,您必须将其链接到您的应用程序二进制文件。

例如main.cpp:

#include <windows.h>
#include "Event_log.h"

void install_event_log_source(const std::string& a_name)

    const std::string key_path("SYSTEM\\CurrentControlSet\\Services\\"
                               "EventLog\\Application\\" + a_name);

    HKEY key;

    DWORD last_error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                      key_path.c_str(),
                                      0,
                                      0,
                                      REG_OPTION_NON_VOLATILE,
                                      KEY_SET_VALUE,
                                      0,
                                      &key,
                                      0);

    if (ERROR_SUCCESS == last_error)
    
        BYTE exe_path[] = "C:\\path\\to\\your\\application.exe";
        DWORD last_error;
        const DWORD types_supported = EVENTLOG_ERROR_TYPE   |
                                      EVENTLOG_WARNING_TYPE |
                                      EVENTLOG_INFORMATION_TYPE;

        last_error = RegSetValueEx(key,
                                   "EventMessageFile",
                                   0,
                                   REG_SZ,
                                   exe_path,
                                   sizeof(exe_path));

        if (ERROR_SUCCESS == last_error)
        
            last_error = RegSetValueEx(key,
                                       "TypesSupported",
                                       0,
                                       REG_DWORD,
                                       (LPBYTE) &types_supported,
                                       sizeof(types_supported));
        

        if (ERROR_SUCCESS != last_error)
        
            std::cerr << "Failed to install source values: "
                << last_error << "\n";
        

        RegCloseKey(key);
    
    else
    
        std::cerr << "Failed to install source: " << last_error << "\n";
    


void log_event_log_message(const std::string& a_msg,
                           const WORD         a_type,
                           const std::string& a_name)

    DWORD event_id;

    switch (a_type)
    
        case EVENTLOG_ERROR_TYPE:
            event_id = MSG_ERROR_1;
            break;
        case EVENTLOG_WARNING_TYPE:
            event_id = MSG_WARNING_1;
            break;
        case EVENTLOG_INFORMATION_TYPE:
            event_id = MSG_INFO_1;
            break;
        default:
            std::cerr << "Unrecognised type: " << a_type << "\n";
            event_id = MSG_INFO_1;
            break;
    

    HANDLE h_event_log = RegisterEventSource(0, a_name.c_str());

    if (0 == h_event_log)
    
        std::cerr << "Failed open source '" << a_name << "': " <<
            GetLastError() << "\n";
    
    else
    
        LPCTSTR message = a_msg.c_str();

        if (FALSE == ReportEvent(h_event_log,
                                 a_type,
                                 0,
                                 event_id,
                                 0,
                                 1,
                                 0,
                                 &message,
                                 0))
        
            std::cerr << "Failed to write message: " <<
                GetLastError() << "\n";
        

        DeregisterEventSource(h_event_log);
    


void uninstall_event_log_source(const std::string& a_name)

    const std::string key_path("SYSTEM\\CurrentControlSet\\Services\\"
                               "EventLog\\Application\\" + a_name);

    DWORD last_error = RegDeleteKey(HKEY_LOCAL_MACHINE,
                                    key_path.c_str());

    if (ERROR_SUCCESS != last_error)
    
        std::cerr << "Failed to uninstall source: " << last_error << "\n";
    


int main(int a_argc, char** a_argv)

    const std::string event_log_source_name("my-test-event-log-source");

    install_event_log_source(event_log_source_name);

    log_event_log_message("hello, information",
                          EVENTLOG_INFORMATION_TYPE,
                          event_log_source_name);

    log_event_log_message("hello, error",
                          EVENTLOG_ERROR_TYPE,
                          event_log_source_name);

    log_event_log_message("hello, warning",
                          EVENTLOG_WARNING_TYPE,
                          event_log_source_name);

    // Uninstall when your application is being uninstalled.
    //uninstall_event_log_source(event_log_source_name);

    return 0;

希望这会有所帮助,但请考虑@Cody Gray 所说的这种方法已被弃用。

【讨论】:

请注意,从 Windows Vista 开始,该 API 已被弃用。新应用程序应使用Windows Event Log API 记录事件。 @CodyGray,ta。从来不知道。旧的 API 仍然有效(据我所知),但我在 Vista 和 Windows 7 上使用它没有问题。 嗨,正如我之前提到的,描述给出了一般描述,我可以在最后添加一些内容,但不会更改“事件查看器”中的整个描述。如果您能指出一个可以在使用 ReportEvent 函数时更改描述的示例,我将不胜感激 首先我要感谢您的完整描述。我正在尝试使用 mc.exe 对其进行编译,但出现错误。您使用哪个 mc.exe? (错误:MC:无效开关:A MC:无效开关:b Microsoft (R) Message Compiler Version 1.00.5239) mc.ex 从 C:\Program Files\Microsoft Visual Studio\VC98\Bin\mc.exe 运行) 尝试添加到.obj 文件列表。此外,您将需要重新启动事件查看器。【参考方案2】:

您正在寻找有关Windows Event Log API 的文档。您需要调用本机 Win32 API 函数,而不是使用 .NET Framework 的包装器,因为您使用的是非托管 C++。

如果您的目标是 Windows Vista 之前的操作系统(XP、Server 2003 等),则需要改用较旧的 Event Logging API。

【讨论】:

您好,我使用了您附加到 Microsoft 的链接,并且有一个很好的示例。但是,没有更改描述的选项,当我转到“事件查看器”并打开描述时,我发现以下行:“找不到源 (MyEventProvider) 中事件 ID (259) 的描述。本地计算机可能没有必要的注册表信息或消息 DLL 文件来显示来自远程计算机的消息。您可以使用 /AUXSOURCE= 标志来检索此描述;有关详细信息,请参阅帮助和支持。以下信息是事件:" 两个链接都指向同一个 URL。

以上是关于将事件写入事件查看器的主要内容,如果未能解决你的问题,请参考以下文章

什么是事件查看器

事件查看器所有事件ID的含义

Windows.old 事件查看器日志

安装oracle11的时候 提示ORA-28056 未能将审计记录写入windows事件日志,这是怎么回事啊

请大家帮忙解决事件查看器中的ID29和17的问题!!!!!

WIN10事件查看器,ID1000,ID1001 问题