杀死流程对窗口焦点的影响

时间:2015-05-29 10:57:23

标签: c# wpf windows

我们的软件包含两个程序。一个exe是守护进程,另一个是主应用程序。当我们的主应用程序正在运行时(守护程序当然还活着),守护程序窗口TopMost设置为false,主应用程序启动并杀死另一个驻留在托盘中的进程(在我们的托盘中看不到并禁用) Windows Embedded)的图像。从主应用程序中停用的其中一个窗口我们杀死第三方进程,而不是回到上一个窗口,我们看到守护进程的窗口。这是因为杀死了第三方应用程序。如果我们不杀它,那么我们的主应用程序会回到正确的窗口。 杀死第三方进程如何导致这种奇怪的行为?

更新

守护进程启动主要应用程序。守护进程有一个窗口实现OnActivated,如下所示:

 private void MainWindow_OnActivated(object sender, EventArgs e) {
        this.Topmost = true;
    }

 private void MainWindow_OnDeactivated(object sender, EventArgs e) {
        this.Topmost = false;
    }

杀死第三方应用程序以停用其中一个主应用程序窗口意味着该OnDeactivated实现如下:

protected override void OnDeactivate(bool close) {
   Process.Kill(procId);
}

“你为什么期望”回到上一个窗口“? 好吧,主应用程序总是有一个窗口,Topmost = true,有时我们打开模态对话框一个在另一个上面。用户无法手动管理窗口,例如最小化窗口。所以我希望通过Caliburn.Micro进入我们试图激活的窗口。但是当我们要求Caliburn激活另一个窗口并且我们杀死驻留在托盘中的那个应用程序时,我们的守护进程窗口将被激活并且最顶层。如果我们注释掉了杀戮,那么我们会看到我们尝试激活的窗口激活。

顺便说一下,我们询问了开发第三方应用程序的同事推出了没有UI的版本。这没有用。这只是猜测而且失败了。

2 个答案:

答案 0 :(得分:2)

在没有访问测试环境的情况下,我的猜测是你不能完全理解OnActivated和OnDeactivated事件何时触发。

终止具有焦点的正在运行的应用程序将导致Windows将焦点转移到另一个应用程序,可能是桌面或其他应用程序。

因为你正在做的就是将Topmost设置为false而不以任何方式隐藏或禁用Window,所以Windows可能会将焦点传递给你的“守护进程”,它会触发{ {1}}事件,然后将OnActivated设置为Topmost

我建议你完全重新考虑你在做什么。

“守护进程”窗口在不显示时应该是不可见的,我认为这样可以解决您的问题。

答案 1 :(得分:0)

通过启动第三方流程解决了问题:

  var process = new Process {
                    StartInfo = {
                        FileName = fileName, 
                        WorkingDirectory = path, 
                        CreateNoWindow = true, 
                        UseShellExecute = false
                    }
                };

此处的关键是使用CreateNoWindow = trueUseShellExecute = falseUseShellExecute = false非常重要,因为否则CreateWindow属性将被忽略。有关详细信息,请查看msdn。

解决方案在@Ashigore的回答之后引起,他的回答带来了Windows在启动第三方应用程序时关注窃取的想法。