Managed C++: Reading and Writing Windows Event Log Entries
Recording Events in an Event LogRecording events using the Win32 SDK involves the following:
- Creating a Windows registry that defines the application as an event source
- Creating a special file with a unique syntax that contains the messages, event IDs, and category IDs to be written
- Compiling that file with the Windows Message Compiler
- Calling the Win32 ReportEvent functionpassing the IDs from the message file
Click here for larger image
Figure 1: Recorded Events in a Custom Event Log
This is much easieralthough admittedly not completely implementedwith .NET 1.1 and the EventLog class. (I'll cover what's changed between 1.1 and 2.0 of the .NET Framework with regards to the Windows Event Log support shortly.) First off, the EventLog::CreateEventSource method takes care of registering the application in the registry as an event source for the specified event log. Secondly, the EventLog::WriteEntry method has many overloads that make it very easy to record events. These overloads take various combinations of values indicating event source, message, event ID, category ID, event type, and even binary data. Here's are some brief explanations of each of these values and its usage:
- Source - The event source, or application, creating the event
- Message - The textual value (which the user can read in the Event Viewer) that describes the reason for the event having been recorded
- Event Type - An enum (represented by the EventLogEntryType) that represents the type of event that was recorded: Information (the default), Warning, Error, SuccessAudit, and FailureAudit
- Event ID - An application-specific number that the user can filter in the Event Viewer
- Category - (Obsolete in .NET 2.0) A means of associating a localized textual description from the message file to the recorded event (.NET 1.1 does not support this feature, so you would need to define and use a message file to realize its benefits. As a result, when using the .NET 1.1 Framework to write events, you can specify only a numeric value and not associate it with a localized textual description. Note the Category column in Figure 1 to see this.)
- Binary data - (Referred to as "raw data") A value that enables you to record information such as a memory dump with the recorded event. (Figure 2 shows an example of what the user would see in the Event Viewer when binary data is written as part of an event.)
Figure 2: Example of using binary data in an event.
Instead of going through each overload of the WriteEntry method, I list several examples illustrating everything from recording a simple informational event to recording an event with binary data:
EventLog* log = new EventLog(S"My Application Log", S".", S"My Application"); // Text (type defaults to EventLogEntryType::Information) log->WriteEntry(S"Informational message"); // Text + Type log->WriteEntry(S"Warning message", EventLogEntryType::Warning); // Text + Type + eventID Int32 eventId = 100; log->WriteEntry(S"Message with event id", EventLogEntryType::SuccessAudit, eventId); // Text + Type + eventID + category Int32 catId = 1000; log->WriteEntry(S"Message with event id and category id", EventLogEntryType::SuccessAudit, eventId, catId); // Text + Type + eventId + category + binaryData. Byte binaryData = new Byte; for (int i = 0; i < 4; i++) binaryData[i] = i; log->WriteEntry(S"Error with event id, category id and binary data", EventLogEntryType::Error, eventId, catId, binaryData);Note that while I instantiate an EventLog object by specifying the log name, machine name, and event source, I could also set these values through the EventLog object's Log, MachineName, and Source properties, respectively.
Clearing Event LogsYou can programmatically clear an event log via the EventLog::Clear method. Here's an example:
EventLog* log = new EventLog(S"My Application Log"); log->Clear();
Looking ForwardThis article illustrated how to enumerate event log entries, read specific event entries, manually filter events based on an event's desired property value, write new event entries, and clear an event log. However, the one thing missing is the ability to write localized event entries; something that's important to many applications in today's distributed computing world. Unfortunately, this is not easily done in version 1.1 of the .NET Framework and must be accomplished via Win32 programming and the Windows Message Compiler. As this is a .NET series, I intentionally omitted this task. However, the good news is that version 2.0 of the .NET Framework does support writing localized events via the new EventLog::WriteEvent method and the EventSourceCreationData class. A future article will cover how to use these additions to the .NET Framework and how they enable the recording of localized events to an event log.
About the Author
Tom Archer owns his own training company, Archer Consulting Group, which specializes in educating and mentoring .NET programmers and providing project management consulting. If you would like to find out how the Archer Consulting Group can help you reduce development costs, get your software to market faster, and increase product revenue, contact Tom through his Web site.
Page 2 of 2