What's Going On? Accessing the Event Log from Visual Basic 6.0 Using the .NET Framework
Swigart Consulting LLC
Visual Basic 6.0
Summary: This article explains how to use .NET Framework classes to add rich event logging functionality to existing Visual Basic 6.0 applications. (6 printed pages)
Click here to download the code sample for this article.
Visual Basic 6.0 provides some ability to write to the event log through App.LogEvent, but this API has a number of serious limitations. First, you aren't able to define the source for your events (it always appears as VBRuntime in the event viewer), and you can't specify the event ID or category. You're also limited to writing to the Application event log, and you can't create your own custom sources and logs.
By using the classes provided (for free) by the .NET Framework, you can overcome all of these limitations, and effectively instrument your applications so that you, administrators, or other support people can look at the logs to diagnose issues.
The .NET Framework provides a powerful EventLog class that makes it trivial to work with the event log. While you can't access this class directly from Visual Basic 6.0, in the spirit of the VB Fusion article series, I've made this functionality accessible from Visual Basic 6.0 by creating a COM wrapper around the .NET classes.
I've also created a sample Visual Basic 6.0 application that exercises this event log functionality (see Figure 1).
Figure 1. Visual Basic 6.0 application that uses event log functionality
Most of the work in creating wrapper classes simply involves converting .NET types to types understood by Visual Basic 6.0. The GetEventLogs method normally returns an array of EventLog objects, and these EventLog objects can't be used directly from Visual Basic 6.0. However, the Visual Basic .NET function shown in Listing 1 returns a list of all the event logs on the machine as an array of strings, which Visual Basic 6.0 can easily consume. Typically, you will have System, Security, and Application event logs, but some applications also create their own custom event logs, and this method will show you those as well.
Listing 1. Listing all the event logs on a machine using Visual Basic .NET
Public Function GetEventLogs() As String() Dim logs(EventLog.GetEventLogs.Length - 1) As String Dim i As Integer = 0 For Each el As EventLog In EventLog.GetEventLogs() logs(i) = el.Log i += 1 Next Return logs End Function
As you can see from Listing 1, the EventLog class lets you access all the event logs through the GetEventLogs function. Once this is called, the function just iterates through the results, and it returns all the event log names as an array of strings. This Visual Basic .NET code can then be exposed as a COM object, allowing it to be called from Visual Basic 6.0.
Calling this from Visual Basic 6.0 and, for example, populating a ListBox with the results is as simple as the code in Listing 2.
Listing 2. Displaying log names in a ListBox using Visual Basic 6.0
Dim eventLog As NetFrameworkWrappers.EventLogWrapper Set eventLog = New NetFrameworkWrappers.EventLogWrapper lstEventLogs.Clear Dim logs() As String logs = eventLog.GetEventLogs Dim log As Variant For Each log In logs lstEventLogs.AddItem log Next
You may want your application to write to the event log for a variety of reasons. Certainly, any catastrophic errors should go into the event log, because this information can be used later to diagnose the problem. Quite often, you may want to write detailed information to the event log that would not be appropriate to show to the user.
The first choice is which log to use. You can choose from the System, Security, or Application event logs. The Application event log is almost always the right choice. However, you can also create your own custom event log if you desire. Listing 3 shows the Visual Basic .NET code in the event log wrapper that lets you create your own custom log.
Listing 3. Creating a custom event log using Visual Basic .NET
Public Sub CreateEventSource(ByVal source As String, ByVal logName As String) If EventLog.SourceExists(source) Then EventLog.DeleteEventSource(source) End If EventLog.CreateEventSource(source, logName) End Sub
As you can see from Listing 3, the .NET Framework makes it easy to create an event log. The .NET CreateEventSource method does all the work for you. This method just exposes that functionality so that it's easy to call it from Visual Basic 6.0 (see Listing 4).
Listing 4. Creating an event log from Visual Basic 6.0 with the wrapper class
Dim eventLog As NetFrameworkWrappers.EventLogWrapper Set eventLog = New NetFrameworkWrappers.EventLogWrapper eventLog.CreateEventSource "MyApplication", "MyCustomLog"
Writing an entry to the event log is equally simple. The WriteEntry Visual Basic .NET method wraps the event log functionality and exposes it so that it can be called from Visual Basic 6.0 (see Listing 5).
Listing 5. Writing an entry to the event log in Visual Basic .NET
Public Sub WriteEntry(ByVal source As String, _ ByVal message As String, _ Optional ByVal type As String = "Information", _ Optional ByVal eventID As Integer = 0, _ Optional ByVal category As Short = 0) Dim typeEnum As EventLogEntryType = _ System.Enum.Parse(GetType(EventLogEntryType), type) m_eventLog.WriteEntry(source, message, typeEnum, eventID, category) End Sub
This wrapper method exposes a number of optional arguments, so when you call it from Visual Basic 6.0, you can pass in just the event log source and message, or also the message type, event ID, and/or category.
You can call this from Visual Basic 6.0 with the code in Listing 6.
Listing 6. Writing an event log entry from Visual Basic 6.0
Dim eventLog As NetFrameworkWrappers.EventLogWrapper Set eventLog = New NetFrameworkWrappers.EventLogWrapper eventLog.WriteEntry cboLog.Text, txtMessage, cboType.Text, _ txtID, txtCategory
Reading the information out of the event logs is only slightly more complex. The .NET Framework EventLog class has a GetEntries method that will return all the log entries for a give event log (Application, System, and so on). The problem is that each entry comes back as an EventLogEntry object, which can't be passed directly back to Visual Basic 6.0. However, it was simple for me to create my own EventLogEntryInfo class that I could copy each event log entry into. This is a full COM Class that can be returned to Visual Basic 6.0, and it exposes properties for the entry source, message, type, ID, and category. The Visual Basic .NET code then fills an array of these with the event log entry data, and returns it so that it can be used from Visual Basic 6.0 (see Listing 7).
Listing 7. Reading and converting event log entries from Visual Basic .NET
Public Sub GetEntries(ByRef entries() As EventLogEntryInfo) ReDim entries(m_eventLog.Entries.Count - 1) For i As Integer = 0 To m_eventLog.Entries.Count - 1 Dim ent As EventLogEntry = m_eventLog.Entries(i) entries(i) = New EventLogEntryInfo entries(i).Category = ent.CategoryNumber entries(i).Message = ent.Message entries(i).Source = ent.Source entries(i).EventID = ent.InstanceId entries(i).EntryType = ent.EntryType Next End Sub
When this function is completed, Visual Basic 6.0 has full access to the event log entries (see Listing 8).
Listing 8. Getting the Event Log entries from Visual Basic 6.0
Dim eventLog As NetFrameworkWrappers.EventLogWrapper Set eventLog = New NetFrameworkWrappers.EventLogWrapper eventLog.Init logName Dim entries() As NetFrameworkWrappers.EventLogEntryInfo eventLog.GetEntries entries
I believe that you don't need to rewrite existing Visual Basic 6.0 applications in order to take advantage of the extensive functionality provided by the .NET framework. As the Visual Basic Fusion articles show, with simple wrapper classes, you can expose the functionality of the .NET Framework as COM objects, which can be used from Visual Basic 6.0, VBA, ASP, or any environment that can access COM objects. In this article, you saw how you could add rich event logging functionality to existing Visual Basic 6.0 applications. Feel free to download the associated sample code to add event logging to your applications today.
About the author
Scott Swigart spends his time consulting, authoring, and speaking about emerging and converging technologies. Scott has worked with a wide range of technologies over his career, beginning with Commodore 64 programming at the age of 12, writing hardware diagnostics for UNIX systems in C++, and building Windows desktop and Web applications. Over the years, Scott has worked with component development, XML technologies, .NET, Web services, and other languages, platforms, and paradigms. With this experience, Scott has seen how technology evolves over time, and he is focused on helping organizations get the most out of the technology of today while preparing for the technology of tomorrow. Scott is also a Microsoft MVP, and co-author of numerous books and articles. Scott can be reached at firstname.lastname@example.org.