Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write an Event to the Event viewer

Tags:

c++

event-log

I found an example in C# how to add new Event to the Event Viewer. But, I need an example written in C++ (not .NET) that create new Event to the Event Viewer under the "Application" part.

like image 309
Moti Avatar asked Dec 19 '11 09:12

Moti


People also ask

How do you write an event log?

The Write-EventLog cmdlet writes an event to an event log. To write an event to an event log, the event log must exist on the computer and the source must be registered for the event log. The cmdlets that contain the EventLog noun (the EventLog cmdlets) work only on classic event logs.

How do I create an event log in Event Viewer?

To generate these logs, please follow the steps listed below: Open "Event Viewer" by clicking the "Start" button. Click "Control Panel" > "System and Security" > "Administrative Tools", and then double-click "Event Viewer" Click to expand "Windows Logs" in the left pane, and then select "Application".

What are the 5 level events the Event Viewer shows?

Windows uses the following levels: Critical, Error, Warning, Information, Verbose (although software developers may extend this set and add own specific levels).


2 Answers

You can use these three functions from the WINAPI:

  • RegisterEventSource
  • ReportEvent
  • DeregisterEventSource

Here is a quick example of how to use these and to display messages correctly in the event log (error handling mostly ignored for brevity).

Create a resource containg message information from the following Event_log.mc file:

;#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

To build the .mc file and .res resource file I executed the following:

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

This will create a header file called Event_log.h in the current directory and a resources directory containing a file named Event_log.res which you must link in to your application binary.

Example 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;
}

Hope this helps but consider that this approach has been deprecated as stated by @Cody Gray.

like image 105
hmjd Avatar answered Oct 12 '22 07:10

hmjd


You're looking for the documentation on the Windows Event Log API. You'll need to call the native Win32 API functions, rather than use the .NET Framework's wrappers, since you're writing in unmanaged C++.

If you're targeting operating systems prior to Windows Vista (XP, Server 2003, etc.), you'll need to use the older Event Logging API instead.

like image 28
Cody Gray Avatar answered Oct 12 '22 06:10

Cody Gray