Мониторинг когда запускается exe

У меня есть некоторые сервисы, которые необходимо запустить приложению, чтобы некоторые его функции работали. Я хотел бы включить возможность запуска внешних служб Windows для инициализации только после запуска приложения. (в отличие от того, чтобы они запускались автоматически на машине и занимали память, когда приложение не нужно)

У меня нет доступа к коду exe-кода, чтобы реализовать это, поэтому в идеале я хотел бы написать службу Windows на C# .Net, которая бы отслеживала его запуск.

На данный момент я обнаружил System.IO.FileSystemEventHandler. Этот компонент обрабатывает только измененные, созданные, удаленные и переименованные типы событий. Я не ожидаю, что компонент файловой системы будет идеальным местом для поиска того, что я ищу, но не знаю, куда еще обратиться.

Возможно, я не ищу правильные ключевые слова, но я еще не нашел ничего чрезвычайно полезного в Google или здесь, на stackru.com.

Решение потребуется для запуска на XP, Vista и Win 7, когда оно появится...

Заранее спасибо за любые указатели.

5 ответов

Решение

Из этой статьи вы можете использовать WMI (System.Management namespace) в вашем сервисе, чтобы следить за событиями запуска процесса.

 void WaitForProcess()
{
    ManagementEventWatcher startWatch = new ManagementEventWatcher(
      new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
    startWatch.EventArrived
                        += new EventArrivedEventHandler(startWatch_EventArrived);
    startWatch.Start();

    ManagementEventWatcher stopWatch = new ManagementEventWatcher(
      new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"));
    stopWatch.EventArrived
                        += new EventArrivedEventHandler(stopWatch_EventArrived);
    stopWatch.Start();
}

  static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) {
    stopWatch.Stop();
    Console.WriteLine("Process stopped: {0}"
                      , e.NewEvent.Properties["ProcessName"].Value);
  }

  static void startWatch_EventArrived(object sender, EventArrivedEventArgs e) {
    startWatch.Stop();
    Console.WriteLine("Process started: {0}"
                      , e.NewEvent.Properties["ProcessName"].Value);
  }
}

WMI позволяет выполнять довольно сложные запросы; Здесь вы можете изменить запросы, чтобы запускать обработчик событий только при запуске отслеживаемого приложения или по другим критериям. Вот краткое введение с точки зрения C#.

У вас есть 3 варианта здесь:

Надежный / навязчивый, настраивает ловушку в неуправляемом коде, который возвращается обратно в ваше приложение C# при каждом запуске приложения. Это трудно понять правильно и включает загрузку дополнительной DLL с каждым процессом. (В качестве альтернативы вы можете настроить драйвер, который еще сложнее написать)

Менее надежный способ - регулярно перечислять все процессы (используя класс System.Diagnostics.Process) (скажем, каждые 10-30 секунд), чтобы увидеть, запущено ли приложение.

Также возможно наблюдать событие WMI Win32_Process, InstanceCreationEvent из управляемого кода. Не уверен, насколько это надежно, но я подозреваю, что это будет лучше, чем процессы опроса.

 public Process IsProcessOpen(string name)
        {
            foreach (Process clsProcess in Process.GetProcesses())
                if (clsProcess.ProcessName.Contains(name))
                    return clsProcess;
            return null;
        }

Отслеживайте, запущен ли процесс - хотя для этого должна быть запущена одна служба.

Если вы действительно не хотите использовать какие-либо ресурсы - напишите простой сервис на простом языке C. Приложение-служба, написанное без MFC/ATL, может потреблять всего 300–400 КБ памяти и практически без циклов ЦП. Когда процесс, который вас интересует, запускается, вы можете запустить свои сервисы C#.

В ответ на Windows 7 это не работает. Если вы отслеживаете 64-битные процессы, ваш процесс также должен быть построен для работы в 64-битном адресном пространстве.

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