我们的软件包含两个程序。一个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的版本。这没有用。这只是猜测而且失败了。
答案 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 = true
和UseShellExecute = false
。 UseShellExecute = false
非常重要,因为否则CreateWindow
属性将被忽略。有关详细信息,请查看msdn。
解决方案在@Ashigore的回答之后引起,他的回答带来了Windows在启动第三方应用程序时关注窃取的想法。