Подписка на журнал событий Windows?
Я работаю над проектом, который должен часто проверять журнал событий Windows на наличие определенных событий. Я задаюсь вопросом:
Is there a way to create a subscription of the Windows Event Log for certain event?
Итак, когда произошло событие (т.е. идентификатор события = 00001), я могу получить уведомление в коде как можно скорее? Я использую C#. Если это не может быть сделано, то мне придется продолжать поиск в журнале событий, который неэффективен.
Спасибо
2 ответа
Поскольку вы используете C#, я думаю, что вы должны использовать Windows API для подписки на определенные события Windows. Вы можете сделать это с помощью класса EventLogWatcher или EventLog. Вы можете найти пример создания подписки на журнал событий Windows с помощью EventLog на MSDN.
Если вы предпочитаете EventLogWatcher, обратитесь к его ограниченной документации. И вот мой пример:
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 IEnumberable 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.");
}
}
Вот упрощенный пример, в котором используется запрос, сгенерированный на вкладке XML в представлении фильтра в средстве просмотра событий Windows. Он загружает начальные записи, возвращаемые запросом, а затем следит за любыми будущими элементами.
var query = $"*[System[(EventID=1942) and TimeCreated[timediff(@SystemTime) <= 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);
}