从 PID 设置活动/前景 window

Set Active / Foreground window from PID

我正在尝试将一个程序(已知 PID)设置为顶部/活动/前景(不确定哪个最合适)。

PID设置为windows进程PID

    handle = win32api.OpenProcess( win32con.PROCESS_ALL_ACCESS,
                        False, pid)
    win32gui.SetForegroundWindow(handle)
    win32gui.SetActiveWindow(handle)

我要么得到:

    pywintypes.error: (1400, 'SetForegroundWindow', 'Invalid window Handle.')

    pywintypes.error: (1400, 'SetActiveWindow', 'Invalid window handle.')

我意识到这是处理程序中的一个问题,但我不确定我应该如何正确获取工作处理程序。

OpenProcess 函数:

如果函数成功,return 值是指定 process.and 的打开句柄,它可用于任何需要进程句柄的函数。

SetForegroundWindow 函数:

它的参数是 window 的句柄,应该被激活并带到前台。

所以你需要这样的翻译:

HWND h = ::GetTopWindow(0 );
while ( h )
{
  DWORD pid;
  DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
         if ( pid == /*your process id*/ )
         {
              // here h is the handle to the window
              break;
         }
         h = ::GetNextWindow( h , GW_HWNDNEXT);
}

一个python版本:

def find_window_for_pid(pid):
    result = None
    def callback(hwnd, _):
        nonlocal result
        ctid, cpid = win32process.GetWindowThreadProcessId(hwnd)
        if cpid == pid:
            result = hwnd
            return False
        return True
    win32gui.EnumWindows(callback, None)
    return result

一些注意事项:

But note that this can easily fail, because when you first launch the process, it probably doesn't have a window until a few milliseconds later. Without some means of synchronizing between the parent and child, there's really no way around this. (You can hack it by, say, sleeping for a second, but that has the same problem as any attempt to sleep instead of synchronizing—most of the time, it'll be way too long, reducing the responsiveness/performance of your code for no reason, and occasionally, when the computer is busy, it'll be too short and fail.)

真正解决这个问题的唯一方法是使用 pywin32 创建进程,而不是使用标准 Python 代码。然后你就掌握了这个过程。这意味着您可以等待子进程开始其 window 循环,然后仅枚举该进程的 windows.

这个工作可以用pywinauto来完成:

from pywinauto import Application
app = Application().connect(process=<pid>)
app.top_window().set_focus()

但它可能不适用于最小化的应用程序。