none
Событие удаления журнала для объекта EventLog RRS feed

  • Общие обсуждения

  • Получаю данные из журнала событий путем подписки на события объекта EventLog:

    EventLog someLog = EventLog.GetEventLogs()
        .Where<EventLog>((l) => { return l.Log == "SomeLogName"; }).First();
    someLog.EntryWritten += SomeHandler;  
    someLog.EnableRaisingEvents = true;

    Вопрос: как можно узнать, что журнал с именем "SomeLogName", с которым связан объект "someLog", был удалён (из другого приложения)?


Все ответы

  • Дополнение:
    Вопрос возникает из проблемы, которая может быть показана в этом примере:

    namespace DeleteLog
    {
        class Program
        {
            static void Main(string[] args)
            {
                string logName = "SomeLog";
                string sourceName = "SomeSource";

                var eventSourceData = new EventSourceCreationData(sourceName, logName);
                if (!EventLog.SourceExists(sourceName))
                    EventLog.CreateEventSource(eventSourceData);

                var log = EventLog.GetEventLogs().Where<EventLog>((l) => { return l.Log == logName; }).First();
                log.Source = sourceName;
                
                Task.Run(() =>
                {
                    while (true)
                    {
                        log.WriteEntry("Test entry", EventLogEntryType.Information, 777);
                        Thread.Sleep(500);
                    }
                }
                );

                Console.WriteLine("Press any key to delete log");
                Console.ReadKey();

                EventLog.Delete(log.Log);

                Console.WriteLine("Log deleted");
                Console.ReadKey();
            }
        }
    }

    После запуска приложения DeleteEventLog (с соответсвующими правами на запись журнала) в журнал с именем SomeLog вносятся записи, которые можно наблюдать с помощью стандартной оснастки EventViewer.

    Далее если запустить приложение LogDeletingProblem:

    namespace LogDeletingProblem
    {
        class Program
        {
            static void Main(string[] args)
            {
                string logName = "SomeLog";
                string sourceName = "SomeSource";
    
                var eventSourceData = new EventSourceCreationData(sourceName, logName);
                if (!EventLog.SourceExists(sourceName))
                    EventLog.CreateEventSource(eventSourceData);
                
                var log = EventLog.GetEventLogs().Where<EventLog>((l) => { return l.Log == logName; }).First();
                log.Source = sourceName;
    
                log.EntryWritten += Log_EntryWritten;
                log.EnableRaisingEvents = true;
                
                Console.ReadKey();
            }
    
            private static void Log_EntryWritten(object sender, EntryWrittenEventArgs e)
            {
                Console.WriteLine("{0}     New entry: {1}",DateTime.Now, e.Entry.Message);
            }
        }
    }

    можно наблюдать оповещения о новых в записях в журнале SomeLog - приложение подписывается на событие EntryWritten и обрабатывает его в Log_EntryWritten(object sender, EntryWrittenEventArgs e).

    Далее после нажатия любой клавиши в приложении DeleteEventLog журнал SomeLog удаляется из системы.

    Я ожидал, что в LogDeletingProblem просто не будут приходить новые оповещения. Однако, в LogDeletingProblem после удаления журнала SomeLog получаю  вот такое:
    Source: System
    Type: System.InvalidOperationException
    Mesage: На компьютере '.' не существует журнала событий 'SomeLog'.
    StackTrace:    в System.Diagnostics.EventLogInternal.OpenForRead(String currentMachineName)
       в System.Diagnostics.EventLogInternal.get_EntryCount()
       в System.Diagnostics.EventLogInternal.CompletionCallback(Object context)
       в System.Diagnostics.EventLogInternal.StaticCompletionCallback(Object context, Boolean wasSignaled)
       в System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(Object state, Boolean timedOut)
       в System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(Object state)
       в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       в System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)

    Отсюда два вопроса:

    1) собственно, как узнать о том что, журнал был удален и отписаться

    2) почему вообще мое приложение получает некорректный callback из системы?