hi
I want to "hook" another application so when it closes I can close my application.
I don't want to poll the running process as this seems unnecessarily intensive, if I want to respond in real-time.
I believe apps send out message within windows when they are created or closed etc how can I hook this to know when it closes?
for example lets say my app loads checks running processes to ensure notepad is loaded and if so it remains loaded until notepad is closed. as notepad is closed my app some how knows this and exits...
is this possible if so how?
it needs to work on xp vista and win7
If you have the Process instance for the running application you can use Process.WaitForExit which will block until the process is closed. Of course you can put the WaitForExit in another thread so that your main thread does not block.
Here is an example, not using a separate thread
Process[] processes = Process.GetProcessesByName("notepad");
if (processes.Length > 0)
{
processes[0].WaitForExit();
}
Here is a simple version using a thread to monitor the process.
public static class ProcessMonitor
{
public static event EventHandler ProcessClosed;
public static void MonitorForExit(Process process)
{
Thread thread = new Thread(() =>
{
process.WaitForExit();
OnProcessClosed(EventArgs.Empty);
});
thread.Start();
}
private static void OnProcessClosed(EventArgs e)
{
if (ProcessClosed != null)
{
ProcessClosed(null, e);
}
}
}
The following Console code is an example of how the above can be used. This would work equally well in a WPF or WinForms app of course, BUT remember that for UI you cannot update the UI directly from the event callback because it it run in a separate thread from the UI thread. There are plenty of examples here on stackoverflow explaining how to update UI for WinForms and WPF from a non-UI thread.
static void Main(string[] args)
{
// Wire up the event handler for the ProcessClosed event
ProcessMonitor.ProcessClosed += new EventHandler((s,e) =>
{
Console.WriteLine("Process Closed");
});
Process[] processes = Process.GetProcessesByName("notepad");
if (processes.Length > 0)
{
ProcessMonitor.MonitorForExit(processes[0]);
}
else
{
Console.WriteLine("Process not running");
}
Console.ReadKey(true);
}
That is easily possible because in Window's a process handle is waitable. Use the Process class to get the process's Handle.
Then use that to construct a SafeHandle, create a WaitHandle. Either wait on that yourself or register with ThreadPool.RegisterWaitForSingleObject() to get a call back when the process closes.