Managed C++: Working with Windows Event Logs

My previous article illustrated how easy it is to access and modify the Windows Registry using the .NET Framework. Continuing with the theme of accessing Windows subsystems, this week’s article shows how you can give your Managed C++ Windows applications a more polished, professional look by using the Windows Event Log to record warning, error, and informational messages.

Working with the Event Log involves quite a few tasks, so this series is divided among several parts. This article illustrates how to accomplish the following Event Log tasks:

  • Enumerate the logs on the local or any connected remote machine (for which the application has sufficient rights)
  • Instantiate an EventLog object for a specific local or remote log
  • Create your own custom event logs that are specific to your application
  • Delete event logs

Future articles will cover how to read and write to the event log (using versions 1.1 and 2.0 of the .NET Framework) and how to monitor the event log for changes.

Important notes before continuing:

  • Because the Event Log is a Windows service, this article pertains only to Windows NT, 2000, XP, 2003, and Longhorn.
  • I could write quite a bit about the Event Log in terms of what it is and why I believe it’s a much better means of recording application messages than using log files. However, I won’t get too much into philosophical issues and instead focus on code. If you are interested in this information, drop me an e-mail and I’ll post an excerpt from my book Extending MFC Applications with the .NET Framework where I cover these issues.

A (Very Quick) Briefing on the Event Log and Viewer

The Windows Event Log is a service that starts when Windows loads. It is used as a central repository for applications to record messages related to the success or failure of their respective tasks. There are three standard, system-supplied logs: Application, Security, and System. Windows also supplies an application for viewing and modifying the logs. You can access this application (called the Event Viewer) via the Windows menu system or by typing eventvwr at the Run prompt. The Event Viewer allows you to search, filter, create views on, back up, and restore event log messages.

Applications (event sources) record messages (events) into a specified log. The exact log an event source uses typically depends on the type of application recording the event. For example, the System event log is used by services and kernel mode programs such as device drivers. The Security event log is used by applications that need to record log-on attempts, suspicious port scans, and other security events. (Note that the Security event log restricts normal-mode applications to read-only access for obvious reasons.) Finally, the Application event log is used by the majority of user-mode Windows applications. In addition to these logs, you also can define your own logs (called custom event logs), which this article also covers.

Instantiating EventLog Objects and Enumerating Event Logs

The main .NET class that you will work with when accessing the Event Log from a Managed C++ application is the Diagnostics::EventLog class. You can construct an EventLog object in the following two ways:

  • Calling one of the EventLog overloaded constructors where you specify such information as the log name, machine name, and the event source name
  • Calling the static EventLog::GetEventLogs method, which returns all logs for which the user has permissions on either the local machine or the specified remote machine

When specifying a log name, realize that log names are not case-sensitive. However, the .NET runtime will throw a System::IO::IOException exception if you specify a log name that is not found. Also note that the local machine can be designated via passing a period (“.”) as the machine name:

// Get local machine's Application log
EventLog* el = new EventLog(S"application");

// Get Application log from the "myserver"
EventLog* e2 = new EventLog(S"application", S"myserver");

// Get Application log from the local machine for the event source
// named "my application"
EventLog* e3 = new EventLog(S"application", S".", S"my application");

To retrieve an array of all of the logs, call the EventLog::GetEventLogs method, where you can pass a string value specifying the machine. Remember that passing a value of “.” indicates the local machine, as does calling the parameterless version of this method:

EventLog* logs[] = EventLog::GetEventLogs();
for (int i = 0; i < logs->Count; i++)
  Console::WriteLine(S"{0}", logs[i]->LogDisplayName);

More by Author

Must Read