6

I don't know if this question was already asked, but I could not find anything on it, so please lead me in the right direction if you can find something.

Basically, I would like to add an event to my current C# program to be raised when another specified process ("example.exe") exits. Is that possible?

If that is not possible, is there, instead, a way to raise an event when a specified process by direct path ("C:\somefolderpaths...\example.exe") exits?

To add: My program does NOT start the process example.exe.

philkark
  • 2,417
  • 7
  • 38
  • 59

2 Answers2

3

If you are using C# 4.0 you can do something like:

 Task.Factory.StartNew(() => 
  { 
      var process = Process.Start("process.exe");
      process.WaitForExit();
  }).ContinueWith(

      //THE CODE THAT WILL RUN AFTER PROCESS EXITED.  

  ); 

EDIT

If you are not creator of a process, you can use Process.GetProcessesByName function to retrive the process from already available ones.

var process = Process.GetProcessesByName("process.exe");

In this way you can avoid blocking your main thread, and run the code you need at the moment external process exited. Meanwhile, continue do something more important.

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • Problem is: I am not starting this process and I cannot specify what will start it. But thank you for the fast answer, I added this information to the question. – philkark Dec 03 '12 at 14:32
  • Can I simply specify the name of the process and not look for it from the current list? – philkark Dec 03 '12 at 14:35
  • @phil13131: what do you mean? where is that list? – Tigran Dec 03 '12 at 14:37
  • Sorry, I mean the current process list. Could I instead of getting the process by `GetProcessByName` simply use a string to specify a process? Because, there might be a chance that I do not know if the process has already started at the point when I want to add the event. – philkark Dec 03 '12 at 14:40
  • @phil13131: just specify a name of the process, and you done. – Tigran Dec 03 '12 at 14:41
  • Will that also work, if the process is not yet running? That is my current problem. – philkark Dec 03 '12 at 14:42
  • no, for sure, not. You can run the timer that checks for that process presence. – Tigran Dec 03 '12 at 14:43
  • @phil13131 If you don't know if it will be running you need to check if it's currently running first. – Servy Dec 03 '12 at 14:43
  • Okay, thank you, I will need to find a solution for this then, but it helps me to raise the event. – philkark Dec 03 '12 at 14:43
  • 1
    Please, correct your method name from `Process.GetProcessByName` to `Process.GetProcessesByName`. – philkark Dec 03 '12 at 14:49
  • If you don't mind asking me. `ContinueWith` requries an `Action`, but I need to access the main thread, which will not be possible anymore. Is there a way around that? – philkark Dec 03 '12 at 16:04
1

You can use the Exited event even when you're not the owner of the process . This code works just fine:

var proc = Process.GetProcessesByName("notepad")[0];

proc.EnableRaisingEvents = true;
proc.Exited += (s, e) => { Console.Write("Done"); };

EnableRaisingEvents happens on the .NET side and has nothing to do with the creation of the process - it has all to do with waiting for the process handle to be signalled. You can do this with any wait handle (and processes are also wait handles), for example like this:

var registration 
 = ThreadPool.RegisterWaitForSingleObject(waitHandle, callbackMethod, null, -1, true);

The only time you're actually using a separate thread (from the thread pool) is while executing the callback. No need to waste a thread doing nothing while you wait.

Of course, if you want to wait as part of a synchronous process, you can still just call WaitForExit, preferrably with a timeout. Or you could just create a simple wrapper around the RegisteredWaitHandle and await.

Luaan
  • 62,244
  • 7
  • 97
  • 116