首先,“hwnd”是一个模棱两可的概念。一个进程可以没有窗口,也可以有 3000 个窗口。
但是假设您碰巧正在运行一个始终只有 1 个窗口的程序,并且您需要知道哪些窗口属于您实际启动的进程,而不是例如已经运行的同一进程的另一个实例。 (否则你可以只按标题和类别搜索。)
因此,您需要一些方法来引用该过程。如果您使用的是os.system 或os.startfile,则无法执行此操作,因此您会被卡住。这只是使用subprocess 模块的众多原因之一:
p = subprocess.Popen(args)
pid = p.pid
现在,您只需 enumerate all top-level windows,然后是 get the PID for each,然后检查哪一个匹配。
假设您安装了pywin32,并且您使用的是 Python 3.x,它看起来像这样:
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
在 Python 2.x 中,没有nonlocal,所以你需要一些其他的方法来从你的回调中获取值到外部函数,比如一个可变虚拟变量的闭包(比如result = [None],然后设置@ 987654334@ 而不是 result)。
但请注意,这很容易失败,因为当您第一次启动该进程时,它可能直到几毫秒后才会有窗口。如果没有一些在父子之间同步的方法,真的没有办法解决这个问题。 (你可以通过睡眠一秒钟来破解它,但这与任何尝试睡眠而不是同步的问题相同——大多数情况下,它会太长,减少无缘无故地影响代码的响应能力/性能,偶尔,当计算机繁忙时,它会太短而失败。)
真正解决这个问题的唯一方法是使用pywin32 到create the process,而不是使用标准的Python 代码。然后你就有了进程的句柄。这意味着您可以wait for the child to start its window loop,然后仅枚举该进程的窗口。