将事件写入事件查看器

时间:2011-12-19 09:20:46

标签: c++ event-log

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

2 个答案:

答案 0 :(得分:19)

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

以下是如何使用这些内容以及在事件日志中正确显示消息的快速示例(为简洁起见,错误处理通常被忽略)。

从以下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所述。

答案 1 :(得分:8)

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

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