如何在C#中将进程窗口聚焦在正在运行的Web浏览器窗口上?

时间:2018-06-28 14:33:42

标签: c# .net winforms setfocus setforegroundwindow

我在Systray中运行着一个小的Windows窗体程序(代理)。用C#编写的该代理的目的是启动其他程序,将它们聚焦并放在前台。

此代理从浏览器接收启动其他程序的命令,并向其报告成功启动。这意味着浏览器始终处于运行状态。

从代理启动外部程序可以正常工作,但是要使焦点和前景主题正常工作很困难。似乎浏览器始终处于焦点位置,并且从代理启动的程序被直接移到浏览器窗口的后面。

我从User32.dll开始尝试了以下方法,但没有成功:

  • SetForegroundWindow(IntPtr handle)
  • SwitchToThisWindow(IntPtr hWnd, bool fAltTab)

奇怪的是,如果我在Visual Studio中运行代理,则焦点工作正常!

非常感谢您的帮助,因为我是Windows内部人员的新手。

更新1:我注意到,例如在浏览器窗口上是否放置了Powershell窗口(可以是任意对象),以使启动的进程窗口按预期工作。

更新2:我能够通过致电来获得正确的关注

SetWindowPos(browserProcess.MainWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

在浏览器进程窗口和

SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

在启动的进程窗口中。但是我认为这是一种不好的方法,因为浏览器窗口可能会在其他打开的窗口之后消失。我也尝试过

SetWindowPos(browserProcess.MainWindowHandle, process.MainWindowHandle, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

切换浏览器窗口和处理窗口的Z顺序,但没有成功。

问题:如何切换浏览器进程和已启动进程的Z顺序?

2 个答案:

答案 0 :(得分:1)

好像SendKeys.SendWait("%");是我需要的魔法。%是ALT键。

摘自LockSetForegroundWindow

的文档
  

如果用户按下ALT键或采取了某些措施导致系统自身更改了前景窗口(例如,单击背景窗口),则系统会自动启用对SetForegroundWindow的调用。

首先致电AllowSetForegroundWindow返回了FALSE,所以我无法设置前台窗口。对GetLastError的调用显示了错误代码ERROR_ACCESS_DENIED。在SendKeys.SendWait("%")之前调用User32dll.SetForegroundWindow(windowHandle)可以成功调用SetForegroundWindow

将其放在一起看起来像这样:

var windowHandle = User32dll.FindWindow(null, nameOfWindow);
SendKeys.SendWait("%");
User32dll.SetForegroundWindow(windowHandle);

如果窗口最小化,则使用User32dll.ShowWindow(windowHandle, User32dll.SW_RESTORE)就足够了。

答案 1 :(得分:0)

如何获取该窗口的句柄

这对我有用:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);


    SetForegroundWindow((IntPtr)handle);