2

I want to read an archived Windows event log file (.evtx), like in this example:

using System;
using System.Diagnostics.Eventing.Reader;

public static class Program {
    static void Main(string[] args) {
        using (var reader = new EventLogReader(@"C:\tmp\some-log.evtx", PathType.FilePath)) {
            EventRecord record;
            while ((record = reader.ReadEvent()) != null) {
                // do something with record...
            }
        }
    }
}

The record object has a Properties list that contains the replacement strings for the event:

foreach (var property in record.Properties) {
    Console.WriteLine(property.Value);
}

If I open the .evtx file in the event log viewer, I can see a full description for the event, which is like a base template message (which should come from a resources file associated to the application that generated the event) with the values for the placeholders replaced with those values:

enter image description here

Is there a way I can get this "message template" for a certain event?

Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193

2 Answers2

3

I've later found out that those "message templates" are available reading the events metadata associated to a certain provider (which is basically a registered source of events).

Here is an example:

using System;
using System.Diagnostics.Eventing.Reader;
using System.Globalization;

public static class Program {

    static void Main(string[] args) {
        foreach (var providerName in EventLogSession.GlobalSession.GetProviderNames()) {
            DumpMetadata(providerName);
        }
    }

    private static void DumpMetadata(string providerName) {
        try {
            ProviderMetadata providerMetadata = new ProviderMetadata(providerName, EventLogSession.GlobalSession, CultureInfo.InvariantCulture);
            foreach (var eventMetadata in providerMetadata.Events) {
                if (!string.IsNullOrEmpty(eventMetadata.Description)) {
                    Console.WriteLine("{0} ({1}): {2}", eventMetadata.Id, eventMetadata.Version, eventMetadata.Description);
                }
            }
        } catch (EventLogException) {
            Console.WriteLine("Cannot read metadata for provider {0}", providerName);
        } 
    }
}
Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
  • By any source, do you know where those metadata is saved in Windows? – Vesper Jun 27 '16 at 07:08
  • @Vesper It's saved in `Computer\HKEY_LOCAL_MACHINE\SYSTEM\{controlSet}\Services\EventLog\{eventLogName}\{providerName}`. – Dai Feb 12 '21 at 01:43
1

If you're examining an Event Log on a different machine than the one it was saved to then you won't have the benefit of EventLogSession.GlobalSession.GetProviderNames(), but provided you can find and mount the machine's HKEY_LOCAL_MACHINE registry hive (located in the C:\Windows\System32\config\SYSTEM file - yes, it's an extensionless file) you can get the event templates from this Registry Key:

HKEY_LOCAL_MACHINE\SYSTEM\{controlSet}\Services\EventLog\{eventLogName}\{providerName}
  • Where {controlSet} is typically "CurrentControlSet" but if you're investigating a machine that died under mysterious circumstances you may need to look at other keys, such as ControlSet001.

    • These "control set" names are involved in the "last-known good configuration" boot option, System Restore, and other parts of the Windows boot process. If a computer won't boot correctly Windows will try other variations of configuration, which have their own separate copy of Event Log configuration.
  • Where {eventLogName} is the name of the log you're looking at. An Event Source is registered for only a single destination log.

  • Where {providerName} corresponds to values in the "Event Source" column in the Windows Event Log Viewer.

Look for a registry value named EventMessageFile, which gives you the path to a Win32 PE (*.exe or *.dll) containing Win32 Resource strings that contain the Event Log Message Templates - you can then read those using standard Win32 resource functions or some other library to extract Win32 resources.

Note that reading event-logs without the message templates extracted from the EventMessageFile is an exercise in pain.

Dai
  • 141,631
  • 28
  • 261
  • 374