Search code examples
c#synchronizationwait

How to wait for process that will be started?


My application need to wait until specific process will be started. I am doing it this way

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

Is there any other way(more elegant) how to accomplish this, with functionality similar to WaitForExit()? Thanks for answers.


Solution

  • Take a look at the ManagementEventWatcher class.

    Specifically, the code example at the bottom of the link shows you how to setup a ManagementEventWatcher to be notified when a new process is created.

    Code copied from MSDN code example (could stand a little cleanup):

    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;
        }
    }
    

    Edit

    Simplifed example with TargetInstance.Name = 'someProcess' filter added.

      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();
      }