Reputation: 551
I'm working on a WPF app which is set up to always be the topmost window. I've added a button to this app which launches an external program that allows the user to calibrate the touchscreen monitor our users will be interacting with.
I've can turn our mainwindow's topmost setting off and launch my app but I need to be able to set our MainWindow.Topmost to true after this external app exits.
It's been suggested that I add an event handler when starting the process that can reset topmost when the process ends. Event Handlers are new to me so I'm not sure how to do this. Can someone walk me through it?
Here's the code I have that currently disables topmost for my main window and launches my application. There's not much to it so far...
Application.Current.MainWindow.Topmost = false;
System.Diagnostics.Process.Start(@"C:\path\to\app.exe");
Many thanks.
(And I'll be reading up on event handlers and delegates this weekend!)
Upvotes: 0
Views: 2392
Reputation: 74832
Create the Process, set EnableRaisingEvents to true and handle the Exited
event:
Process p = new Process();
p.StartInfo.FileName = pathToApp;
p.EnableRaisingEvents = true;
p.Exited += OnCalibrationProcessExited; // hooks up your handler to the Process
p.Start();
// Now .NET will call this method when the process exits
private void OnCalibrationProcessExited(object sender, EventArgs e)
{
// set Topmost
}
From the comments thread, the Exited event gets raised on a worker thread, so you will need to do use Dispatcher.BeginInvoke to switch over to the UI thread to set Topmost:
private void OnCalibrationProcessExited(object sender, EventArgs e)
{
Action action = () => { /* set Topmost */ };
Dispatcher.BeginInvoke(DispatcherPriority.Normal, action);
}
(This assumes the code is in your Window class. If not, you will need to write something like Application.Current.MainWindow.Dispatcher.BeginInvoke(...)
instead.)
Note I have separated creating and configuring the Process object from starting it. Although this is more verbose, it is necessary to ensure that all the event handling stuff is in place before the process starts -- otherwise the process could exit before you put the handler in place (unlikely, but theoretically possible!) and your handler would never get called.
Upvotes: 2
Reputation: 564831
You can wait for the process to exit via Process.WaitForExit:
Application.Current.MainWindow.Topmost = false;
var process = System.Diagnostics.Process.Start(@"C:\path\to\app.exe");
process.WaitForExit();
Application.Current.MainWindow.Topmost = true;
If you want to provide a timeout value to prevent the process from waiting forever, that is also possible. For example, if you wanted to wait for a maximum of 2 minutes, you could do:
process.WaitForExit(2 * 60000); // 60000ms/minute
Upvotes: 1