启动外部进程并在完成后设置值

时间:2011-02-11 22:15:42

标签: c# wpf event-handling

我正在开发一个WPF应用程序,该应用程序设置为始终是最顶层的窗口。我在这个应用程序中添加了一个按钮,它启动了一个外部程序,允许用户校准我们的用户将与之交互的触摸屏监视器。

我可以将主窗口的最顶层设置关闭并启动我的应用程序,但我需要能够在外部应用程序退出后将MainWindow.Topmost设置为true。

有人建议我在启动进程时添加一个事件处理程序,该进程可以在进程结束时重置最顶层。事件处理程序对我来说是新的,所以我不知道如何做到这一点。有人可以带我走过吗?

这是我的代码,它当前禁用了我的主窗口的最顶层并启动了我的应用程序。到目前为止还没有多少......

            Application.Current.MainWindow.Topmost = false;
            System.Diagnostics.Process.Start(@"C:\path\to\app.exe");

非常感谢。

(我将在本周末阅读活动处理人员和代表!)

2 个答案:

答案 0 :(得分:2)

创建Process,将EnableRaisingEvents设置为true并处理Exited事件:

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
}

在评论主题中,Exited事件会在工作线程上引发,因此您需要使用Dispatcher.BeginInvoke切换到UI线程来设置Topmost:

private void OnCalibrationProcessExited(object sender, EventArgs e)
{
  Action action = () => { /* set Topmost */ };
  Dispatcher.BeginInvoke(DispatcherPriority.Normal, action);
}

(这假设代码在您的Window类中。如果没有,您将需要编写类似Application.Current.MainWindow.Dispatcher.BeginInvoke(...)的内容。)

注意我已将创建和配置Process对象与启动它分开了。虽然这更详细,但有必要确保在进程开始之前所有事件处理内容都已到位 - 否则进程可能会在处理程序到位之前退出(不太可能,但理论上可能!)你的处理程序永远不会被调用。

答案 1 :(得分:1)

您可以等待该过程通过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;

如果要提供超时值以防止进程永远等待,这也是可能的。例如,如果您想等待最多2分钟,则可以执行以下操作:

process.WaitForExit(2 * 60000); // 60000ms/minute