Subscription to Windows Event Log?
Asked Answered
V

2

13

I'm working on a project that needs to check the Windows Event Log frequently for certain events. I'm wondering - is there a way to create a subscription to the Windows Event Log for certain events?

So, when the event happens (e.g. event id = 00001), I can get a notification in the code?

If this cannot be done, then I will have to keep searching the event log, which is not efficient.

Venery answered 3/11, 2015 at 22:23 Comment(1)
to check the Event log there are several ways best way that I have found in the past was to use WMI worked wonders for me..Scheelite
V
27

As you're using C#, I think you should use Windows API to subscribe to certain Windows events. You can do it by using either EventLogWatcher or EventLog class. You can find an example of creating a Windows Event Log subscription using EventLog on MSDN.

If you prefer EventLogWatcher, refer to its limited documentation.

And here is my example:

public static void subscribe()
{
    EventLogWatcher watcher = null;
    try
    {
        EventLogQuery subscriptionQuery = new EventLogQuery(
            "Security", PathType.LogName, "*[System/EventID=4624]");

        watcher = new EventLogWatcher(subscriptionQuery);

        // Make the watcher listen to the EventRecordWritten
        // events.  When this event happens, the callback method
        // (EventLogEventRead) is called.
        watcher.EventRecordWritten +=
            new EventHandler<EventRecordWrittenEventArgs>(
                EventLogEventRead);

        // Activate the subscription
        watcher.Enabled = true;

        for (int i = 0; i < 5; i++)
        {
            // Wait for events to occur. 
            System.Threading.Thread.Sleep(10000);
        }
    }
    catch (EventLogReadingException e)
    {
        Log("Error reading the log: {0}", e.Message);
    }
    finally
    {
        // Stop listening to events
        watcher.Enabled = false;

        if (watcher != null)
        {
            watcher.Dispose();
        }
    }
    Console.ReadKey();
}

// Callback method that gets executed when an event is
// reported to the subscription.
public static void EventLogEventRead(object obj,
    EventRecordWrittenEventArgs arg)
{
    // Make sure there was no error reading the event.
    if (arg.EventRecord != null)
    {
        //////
        // This section creates a list of XPath reference strings to select
        // the properties that we want to display
        // In this example, we will extract the User, TimeCreated, EventID and EventRecordID
        //////
        // Array of strings containing XPath references
        String[] xPathRefs = new String[9];
        xPathRefs[0] = "Event/System/TimeCreated/@SystemTime";
        xPathRefs[1] = "Event/System/Computer";
        xPathRefs[2] = "Event/EventData/Data[@Name=\"TargetUserName\"]";
        xPathRefs[3] = "Event/EventData/Data[@Name=\"TargetDomainName\"]";

        // Place those strings in an IEnumerable object
        IEnumerable<String> xPathEnum = xPathRefs;

        // Create the property selection context using the XPath reference
        EventLogPropertySelector logPropertyContext = new EventLogPropertySelector(xPathEnum);

        IList<object> logEventProps = ((EventLogRecord)arg.EventRecord).GetPropertyValues(logPropertyContext);
        Log("Time: ", logEventProps[0]);
        Log("Computer: ", logEventProps[1]);
        Log("TargetUserName: ", logEventProps[2]);
        Log("TargetDomainName: ", logEventProps[3]);
        Log("---------------------------------------");

        Log("Description: ", arg.EventRecord.FormatDescription());
    }
    else
    {
        Log("The event instance was null.");
    }
}
Villa answered 26/11, 2015 at 14:14 Comment(1)
i'll second that their documentation is terribleBefriend
S
2

Here is a simplified example, which uses the query generated in the XML tab on the filter view of the Windows Event Viewer. It loads the initial records returned by the query, then keeps watch for any future items.

var query = $"*[System[(EventID=1942) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]]";
var decoded = System.Web.HttpUtility.HtmlDecode(query);
var eventLogQuery = new EventLogQuery("Application", PathType.LogName, decoded);
var watcher = new EventLogWatcher(eventLogQuery, null, true);
var count = 0;

watcher.EventRecordWritten += (object sender, EventRecordWrittenEventArgs e) =>
{
    count += 1;

    Console.WriteLine($"Found {count} items for query");
};

watcher.Enabled = true;

for (var i = 0; i < 5; i++)
{ 
    System.Threading.Thread.Sleep(10000);
}
Superelevation answered 1/6, 2021 at 13:46 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.