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 ..
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With