WMI-запрос - найти самое старое событие в журнале приложений

Я просмотрел все актуальные темы, но не нашел ответа. Я выполняю запрос WMI, чтобы получить дату и время самого старого события в журнале приложений. К сожалению, приведенный ниже запрос всегда возвращает 0 значений, но, по-видимому, синтаксис правильный, поскольку сообщение об ошибке не возвращается. Есть идеи, почему это происходит? На самом деле встроенное решение C# загружает весь Eventviewer, и, поскольку я подключаюсь к удаленным машинам, производительность ужасна. Поэтому я выбрал WMI запрос

SelectQuery query = new SelectQuery("select * from Win32_NtLogEvent where Logfile ='" + logFileName + "' and RecordNumber = '1'");

using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, opt)) {
    foreach (ManagementObject mo in searcher.Get()) {
         DateTime firstEventTime;
         DateTime.TryParseExact(mo["TimeGenerated"].ToString().Substring(0, 12), "yyyyMMddHHmm", null, DateTimeStyles.None, out firstEventTime);
         // if the time of the first entry of the application log is older that the dayback to check date
         // set dayback to check to first app log entry date
         logbox.writetoLogFile(this.GetType().Name, "First event time is " + firstEventTime, LogLevel.Debug);
             if (firstEventTime > endDate) {
                 endDate = firstEventTime;
                 logbox.writetoLogTextbox("First eventviewer entry has date " + firstEventTime + ". Check log will stop at this date", Color.Black);
                 logbox.writetoLogFile(this.GetType().Name, "First eventviewer entry has date " + firstEventTime + ". Check log will stop at this date", LogLevel.Info);
             }
     }
}

К сожалению, я понял это сейчас. Номер записи не сбрасывается, поэтому событие 1 исчезло с давних пор. Есть идеи, как я мог собрать эту информацию?

Спасибо марко

1 ответ

RecordNumber является уникальным идентификатором и не обязательно совпадает с используемым вами LogFile, это что-то вроде первичного ключа, и вы получаете разные числа для каждого компьютера, определение msdn для RecordNumber:

  • Определяет событие в файле журнала событий Windows NT. Это относится к файлу журнала и используется вместе с именем файла журнала для уникальной идентификации экземпляра этого класса.

Итак, что вы должны сделать, это получить все события с определенным LogFile, отсортировать по TimeGenerated и получить старое событие и выполнить другой поиск номера более старого события: т.е.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Management;

namespace WmiEventQuery
{
    class Program
    {
        static void Main(string[] args)
        {
            SelectQuery query = new SelectQuery("select * from Win32_NtLogEvent where LogFile = 'Application' ");
            //execute the query using WMI
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            //loop through each log found
            List<EventDateTime> datetimesEvents = new List<EventDateTime>();
            foreach (ManagementObject mo in searcher.Get())
            {
                DateTime firstEventTime;
                DateTime.TryParseExact(mo["TimeGenerated"].ToString().Substring(0, 12), "yyyyMMddHHmm", null, DateTimeStyles.None, out firstEventTime);

                datetimesEvents.Add(new EventDateTime
                {
                    RecordNumber = Convert.ToInt32(mo["RecordNumber"]),
                    TimeGenerated = firstEventTime
                });
            }

            int olderRecordNumber = datetimesEvents.OrderBy(p => p.RecordNumber).FirstOrDefault().RecordNumber;

            SelectQuery queryUnique = new SelectQuery(
                System.String.Format("select * from Win32_NtLogEvent where RecordNumber = {0}", olderRecordNumber)
                );

            ManagementObjectSearcher searcherUnique = new ManagementObjectSearcher(queryUnique);

            foreach (ManagementObject mo in searcherUnique.Get())
            {
                //get the older event
                Console.WriteLine(mo["Message"]);
                Console.WriteLine(mo["RecordNumber"]);
            }

            Console.Read();

        }
    }

    public class EventDateTime
    {
        public DateTime TimeGenerated { get; set; }
        public int RecordNumber { get; set; }
    }

}
Другие вопросы по тегам