简体   繁体   中英

Parent process and child process relation

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

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

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.

I've made a child process management library where the parent process and the child process are monitored due a bidirectional WCF pipe. If either the child process terminates or the parent process terminates each other is notified. There is also a debugger helper available which automatically attaches the VS debugger to the started child process.

The bidirectional WCF channel is extendable and you can handle process start and process terminate events.

Project site:

http://www.crawler-lib.net/child-processes

NuGet Packages:

https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM