我们的软件包含两个程序 . 一个exe是守护进程,另一个是主应用程序 . 当我们的主应用程序正在运行时(守护程序当然还活着),守护程序窗口 TopMost
设置为 false
,主应用程序启动并终止另一个驻留在托盘中的进程(在我们的 Windows Embedded
图像中不可见并禁用) . 从主应用程序中停用的其中一个窗口我们杀死第三方进程,而不是回到上一个窗口,我们看到守护进程的窗口 . 这是因为杀死了第三方应用程序 . 如果我们不杀它,那么我们的主应用程序会回到正确的窗口 . 杀死第三方进程如何导致这种奇怪的行为?
UPDATE
守护进程启动主要应用程序 . 守护进程有一个窗口实现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 回答
在没有访问测试环境的情况下,我的猜测是你没有完全理解OnActivated和OnDeactivated事件何时触发 .
终止具有焦点的正在运行的应用程序将导致Windows将焦点转移到另一个应用程序,可能是桌面或其他应用程序 .
因为你正在做的就是将
Topmost
设置为false
,它不会以任何方式隐藏或禁用窗口,很可能是Windows将焦点传递给"daemon",它会触发OnActivated
事件,而事件又将Topmost
设置为true
.我建议你完全重新思考你在做什么 .
“守护进程”窗口在不显示时应该是不可见的,我认为这将解决您的问题 .
通过启动第三方流程解决了以下问题:
这里的关键是使用
CreateNoWindow = true
和UseShellExecute = false
.UseShellExecute = false
非常重要,否则将忽略CreateWindow
属性 . 有关详细信息,您可以查看msdn .解决方案是在@Ashigore的回答之后引起的,他的回答带来了Windows在启动第三方应用程序时关注窃取的想法 .