Мониторинг когда запускается 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-битном адресном пространстве.