Как ждать процесса, который будет запущен? - PullRequest
6 голосов
/ 04 июля 2011

Мое приложение должно ждать, пока не запустится определенный процесс.Я делаю это следующим образом

while (Process.GetProcessesByName("someProcess").Length == 0)
{
    Thread.Sleep(100);
}

Есть ли другой способ (более элегантный), как это сделать, с функциональностью, аналогичной WaitForExit ()?Спасибо за ответы.

Ответы [ 2 ]

8 голосов
/ 04 июля 2011

Взгляните на ManagementEventWatcher класс.

В частности, пример кода в нижней части ссылки показывает, как настроить ManagementEventWatcher, чтобы получать уведомления при создании нового процесса.

Код, скопированный с примера кода MSDN (может выдержать небольшую очистку):

using System;
using System.Management;

// This example shows synchronous consumption of events. 
// The client is blocked while waiting for events. 

public class EventWatcherPolling 
{
    public static int Main(string[] args) 
    {
        // Create event query to be notified within 1 second of 
        // a change in a service
        WqlEventQuery query = 
            new WqlEventQuery("__InstanceCreationEvent", 
            new TimeSpan(0,0,1), 
            "TargetInstance isa \"Win32_Process\"");

        // Initialize an event watcher and subscribe to events 
        // that match this query
        ManagementEventWatcher watcher =
            new ManagementEventWatcher();
        watcher.Query = query;
        // times out watcher.WaitForNextEvent in 5 seconds
        watcher.Options.Timeout = new TimeSpan(0,0,5);

        // Block until the next event occurs 
        // Note: this can be done in a loop if waiting for 
        //        more than one occurrence
        Console.WriteLine(
            "Open an application (notepad.exe) to trigger an event.");
        ManagementBaseObject e = watcher.WaitForNextEvent();

        //Display information from the event
        Console.WriteLine(
            "Process {0} has been created, path is: {1}", 
            ((ManagementBaseObject)e
            ["TargetInstance"])["Name"],
            ((ManagementBaseObject)e
            ["TargetInstance"])["ExecutablePath"]);

        //Cancel the subscription
        watcher.Stop();
        return 0;
    }
}

Редактировать

Упрощенный пример с добавленным фильтром TargetInstance.Name = 'someProcess'.

  var query = new WqlEventQuery(
                "__InstanceCreationEvent", 
                new TimeSpan(0, 0, 1), 
                "TargetInstance isa \"Win32_Process\" and TargetInstance.Name = 'someProcess'"
              );

  using(var watcher = new ManagementEventWatcher(query))
  {
    ManagementBaseObject e = watcher.WaitForNextEvent();

    //someProcess created.

    watcher.Stop();
  }
2 голосов
/ 04 июля 2011

Насколько я знаю, в классе Process нет ничего, что сделало бы его простым.

Если у вас нет контроля над исходным кодом в подпроцессе, то вам, вероятно, следует использовать решение WMI, предоставленное Calgary Coder.

Если у вас есть контроль над кодом в подпроцессе, есть несколько дополнительных способов решения этой проблемы. Я использовал WCF (используя привязку IPC ), .Net Remoting и Mutex .

Преимущество этих решений заключается в том, что подпроцесс должен включить его. Подпроцесс может подождать, пока он завершит свои процедуры инициализации запуска, прежде чем сообщить родительскому приложению, что оно «готово».

В каждой из этих ссылок есть примеры, которые должны дать вам старт для решения этой проблемы. Если вы заинтересованы в работе с конкретным приложением и у вас есть проблемы, дайте мне знать, и я опубликую пример кода для этого конкретного решения.

...