tags:

views:

115

answers:

3

Hi all

I have parent process that opens child process . I need to perform some functionality only when the parent process is no more running.

What is the best way to know that the parent process is not running ? Because it can be terminated violently then I don't want to make some functionality that will send signal to my child process on the closing event.

Or just looking for my parent process like that:

In the parent make this and pass it to the child Process.GetCurrentProcess().Id And in the child every several milliseconds check this one

Process localById = Process.GetProcessById(1234);

Any ideas ? Recommendations ..

+3  A: 

The underlying Win32 process handle is waitable, and will be signalled when the process exits.

In native code:

DWORD res = WaitForSIngleObject(hProcess, INFINITE);
if (res == WAIT_OBJECT_0) {
  // process has exited.
}

In native code, you'll need to either create a custom subtype of WaitHandle for process handles, or use P/Invoke. The disadvantage of P/Invoke is that it is harder to combine (using WaitForMultipleObjects multiple waits, so you are not dedicating a thread just to wait on one thing).


Thanks to 0xA3: Just use Process.WaitForExit (there is an overload with a timeout to avoid indefinite waits, and don't do this on your UI thread).

Richard
Sorry not really want going to Native Code .
Night Walker
@Night Walker: No need to do so, simply use `Process.WaitForExit`. probably best in a separate thread.
0xA3
@0xA3: And sometimes MS has already done the work for you...
Richard
But i need to wait in the child process for the father process. Not sure how Process.WaitForExit can help.
Night Walker
@NightWalker: Either the parent process passes the child process the parent process's id (e.g. on command line), or use WMI and Win32_Process request for the child's process and use the parent process id property. Once you have the parent process's id you can get a Process instance with `Process.GetProcessById()`.
Richard
A: 

When the parent process starts the child process, pass the parents process ID to the child via command line arguments.

Then on the child process, use the Process.GetProcessById(int) to get the parent process and use Process.WaitForExit(). Alternatively, you use the Process.Exited event to get a notification when the parent process exits (remember to set Process.EnableRaisingEvents to true, otherwise the event will not be raised).

Allon Guralnek
+1  A: 

Here is a simple example how to use Process.WaitForExit to check for a parent process whose id has been passed on the command line:

using System;
using System.Diagnostics;
using System.Threading;

class Program
{
    static AutoResetEvent _autoResetEvent;

    static void Main(string[] args)
    {
        int parentProcessId = int.Parse(args[0]);

        _autoResetEvent = new AutoResetEvent(false);

        WaitCallback callback = delegate(object processId) { CheckProcess((int)processId); };
        ThreadPool.QueueUserWorkItem(callback, parentProcessId);

        _autoResetEvent.WaitOne();
    }

    static void CheckProcess(int processId)
    {
        try
        {
            Process process = Process.GetProcessById(processId);
            process.WaitForExit();
            Console.WriteLine("Process [{0}] exited.", processId);
        }
        catch (ArgumentException)
        {
            Console.WriteLine("Process [{0}] not running.", processId);
        }

        _autoResetEvent.Set();
    }
}

Using the Process.Exited event could be done like this:

using System;
using System.Diagnostics;
using System.Threading;

class Program
{
    static AutoResetEvent _autoResetEvent;

    static void Main(string[] args)
    {
        int parentProcessId = int.Parse(args[0]);
        Process process = Process.GetProcessById(parentProcessId);
        process.EnableRaisingEvents = true;
        process.Exited += new EventHandler(process_Exited);

        _autoResetEvent = new AutoResetEvent(false);
        _autoResetEvent.WaitOne();
    }

    static void process_Exited(object sender, EventArgs e)
    {
        Console.WriteLine("Process exit event triggered.");
        _autoResetEvent.Set();
    }
}

Note that in both samples the purpose of the AutoResetEvent is solely to prevent your main thread from exiting. In a Windows Forms application you would not need to use it as your program will be in a message loop and only exit if you close it.

0xA3
I have used the Process.Exited example . Really thanks for good explanation.
Night Walker