如何在 c# 中将进程 window 集中在 运行 网络浏览器 window 上?

How to focus a process window over a running webbrowser window in c#?

我在系统托盘中有一个小的 Windows 表单程序(代理)运行。 C#写的这个agent的目的是启动其他程序,将它们聚焦并放到前台。

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

从代理启动外部程序工作正常,但我很难让焦点和前景主题工作。似乎浏览器始终处于焦点状态,并且从代理启动的程序被移到浏览器后面window。

我尝试了 User32.dll 中的以下方法但没有成功:

奇怪的是,如果我是 运行 我 Visual Studio 中的代理人,焦点工作完美!

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

更新 1: 我注意到如果例如一个 powershell window(可以是任意的)覆盖浏览器 window,关注启动的进程window 按预期工作。

更新 2: 我可以通过调用

获得正确的焦点
SetWindowPos(browserProcess.MainWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

在浏览器进程上 window 和

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

在启动过程中 window。但我认为这是一个糟糕的方法,因为浏览器 window 可能会在其他打开的 windows 之后消失。我也试过

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

切换浏览器window和进程window的Z序,但是没有成功。

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

如何检索 window 的 句柄

这对我有用:

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


    SetForegroundWindow((IntPtr)handle);

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

来自 LockSetForegroundWindow

的文档

The system automatically enables calls to SetForegroundWindow if the user presses the ALT key or takes some action that causes the system itself to change the foreground window (for example, clicking a background window).

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

把它放在一起看起来像这样:

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

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