如何激活Window由另一个进程启动
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何激活Window由另一个进程启动相关的知识,希望对你有一定的参考价值。
我想这可能是不可能的。请证明我错了。
以下设置:
- 我的带有GUI的.NET C#应用程序(让我们称之为
gui
)通过创建一个server
打开另一个应用程序(让我们称之为new Process()
) server
(由其他人开发)以一个参数来启动,以隐藏其GUIgui
等待用户做出一些输入- 然后
gui
命令server
执行一些任务 - 这些任务在我提供给
server
的程序集/ DLL中定义 - 其中一项任务是打开表单/对话框并向用户询问更多问题
现在因为需要针对重复操作优化整体使用体验,所以打开的GUI元素(窗口/窗体/对话框)需要预先选择/聚焦/激活。
第一个问题出现了,因为我没有找到difference between those属性(Focus,Active,Selected,TopMost)的明确解释。
现在真正的问题是,我如何确保所有GUI元素都处于活动状态并被选中,无论它们是由我的gui
进程还是server
进程启动的?
使用WINAPI可以更强大我阅读所以我定义了以下内容
// required to use WINAPI for RegainFocus();
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SetActiveWindow(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static private void RegainFocus()
{
// set focus back to and show application for faster input
// SW_RESTORE = 9
ShowWindow(Process.GetCurrentProcess().MainWindowHandle, 9);
SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle);
SetActiveWindow(Process.GetCurrentProcess().MainWindowHandle);
}
然后我到目前为止尝试的是:
- 像这样设置
StartInfo
过程的server
(所以新过程不会窃取gui
的焦点)myProcess.StartInfo.UseShellExecute = false; myProcess.StartInfo.CreateNoWindow = true; myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
- 启动
server
流程和WaitForInputIdle
(如描述here)以确保server
真的准备好了 - 也可以在
RegainFocus()
应用程序中使用gui
- 在
server
的DLL中,我创建了一个新的Form()
并尝试(将窗口置于前面并选择它)myForm = new Form(); myForm.Activated += dialog_Activated; myForm.PerformLayout(); myForm.TopMost = true; myForm.Activate(); myForm.BringToFront(); myForm.Focus(); myForm.Select(); DialogResult result = myForm.ShowDialog();
TopMost=true
致力于在gui
面前展示对话dialog_Activated()
方法使用FocusControl()
将Focus设置为第一个输入控件。这有效。
结果是我的gui
顶部有一个窗口,它在第一个输入控件中闪烁,但是取消选择/不活动。当我点击<TAB>
时,我可以看到在背景中的gui
中选择了不同的控件。
我尝试在表格中喷涂RegainFocus()
电话,没有用。
我有进一步的想法,但无法实现它们:
- 一旦输入在那里完成散焦
gui
,但there is nounFocus()
- 覆盖我的Form类中的some important events,但how and which的?
Target Framework是.NET 4.5,目标操作系统是Windows 7和Windows 10。
感谢您的帮助和输入/ tipps!
我得到了一个似乎适用于Windows 10和Windows 7的解决方案。
在我的焦点丢失后,我使用RegainFocus()
函数重新获得焦点(并激活窗口),请参阅问题。注意:不要混合过程HANDLE
和MainWindowHandle
。当一个物体被隐藏时,它的MainWindowHandle
很可能是0
。
我删除了
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
在启动server
进程时,为了不干扰可见性状态。我保留了[WaitForInputIdle][1]
。
在Windows 7上,这仍然不够,并且AllowSetForegroundWindow在创建的进程上不起作用(感谢评论),而不是将窗口带到前面,taskbar was flashing。这里的解决方案是set the registry value的
\HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundLockTimeout
到0
并重新启动机器。然后代码对于Windows 7和10的行为相同。使用正确的权限,这甚至可能是done programatically。
由于这个问题有很多不同的答案和解决方案,我认为它取决于许多因素(如Windows版本,注册表设置,可能是UAC和主题设置,框架和运行时,一些more conditions,...)这就是我想要的原因提到我发现的其他方法。
- Minimizing在展示它之前的窗口
- 在Simulating a keypress之前的
SetForegroundWindow
- Sending一个
WM_SHOWWINDOW
消息 ShowWindow
与SW_RESTORE
和SW_SHOW
beforeSetForegroundWindow
- Qazxswpoi,combination,
[SetWindowPos][10]
和SetActiveWindow
的SetFocus
- qazxsw poi qazxsw poi与qazxsw poi
AttachThreadInput
锁定- Use
AllowSetForegroundWindow
[ASFW_ANY][11]
Disable SetForegroundWindow - Use是最顶尖的
以上是关于如何激活Window由另一个进程启动的主要内容,如果未能解决你的问题,请参考以下文章
C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题
LINUX PID 1和SYSTEMD PID 0 是内核的一部分,主要用于内进换页,内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程(代码片段