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

RX, вероятно, самый простой выбор, особенно если вы уже используете его в своем приложении. Но если нет, то добавление может быть немного излишним.

Для приложений на основе пользовательского интерфейса (например, WPF) я использую следующий класс, который использует DispatcherTimer:

public class DebounceDispatcher
{
    private DispatcherTimer timer;
    private DateTime timerStarted { get; set; } = DateTime.UtcNow.AddYears(-1);

    public void Debounce(int interval, Action<object> action,
        object param = null,
        DispatcherPriority priority = DispatcherPriority.ApplicationIdle,
        Dispatcher disp = null)
    {
        // kill pending timer and pending ticks
        timer?.Stop();
        timer = null;

        if (disp == null)
            disp = Dispatcher.CurrentDispatcher;

        // timer is recreated for each event and effectively
        // resets the timeout. Action only fires after timeout has fully
        // elapsed without other events firing in between
        timer = new DispatcherTimer(TimeSpan.FromMilliseconds(interval), priority, (s, e) =>
        {
            if (timer == null)
                return;

            timer?.Stop();
            timer = null;
            action.Invoke(param);
        }, disp);

        timer.Start();
    }
}

Для его использования:

private DebounceDispatcher debounceTimer = new DebounceDispatcher();

private void TextSearchText_KeyUp(object sender, KeyEventArgs e)
{
    debounceTimer.Debounce(500, parm =>
    {
        Model.AppModel.Window.ShowStatus("Searching topics...");
        Model.TopicsFilter = TextSearchText.Text;
        Model.AppModel.Window.ShowStatus();
    });
}

События клавиш теперь обрабатываются только после клавиатуры не используется в течение 200 мс - все предыдущие ожидающие события отбрасываются.

Существует также метод Throttle, который всегда запускает события после заданного интервала:

    public void Throttle(int interval, Action<object> action,
        object param = null,
        DispatcherPriority priority = DispatcherPriority.ApplicationIdle,
        Dispatcher disp = null)
    {
        // kill pending timer and pending ticks
        timer?.Stop();
        timer = null;

        if (disp == null)
            disp = Dispatcher.CurrentDispatcher;

        var curTime = DateTime.UtcNow;

        // if timeout is not up yet - adjust timeout to fire 
        // with potentially new Action parameters           
        if (curTime.Subtract(timerStarted).TotalMilliseconds < interval)
            interval = (int) curTime.Subtract(timerStarted).TotalMilliseconds;

        timer = new DispatcherTimer(TimeSpan.FromMilliseconds(interval), priority, (s, e) =>
        {
            if (timer == null)
                return;

            timer?.Stop();
            timer = null;
            action.Invoke(param);
        }, disp);

        timer.Start();
        timerStarted = curTime;            
    }
20
задан 9 June 2009 в 00:22
поделиться

3 ответа

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

 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 #.

34
ответ дан 29 November 2019 в 23:57
поделиться

у вас есть 3 варианта:

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

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

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

5
ответ дан 29 November 2019 в 23:57
поделиться

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

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

0
ответ дан 29 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: