How do I get the window for a subprocess.Popen object?
[This only applies to Win32, obviously!]
Perhaps you want to be able to close an app cleanly by sending it a WM_CLOSE? Or maybe you want to minimize it on demand? To do that you have to get the hWnd of its top-level window. You’d have thought there’d be some kind of get-window-from-process-id API call, wouldn’t you? Well, according to all the available literature, there isn’t. (Maybe there is in .NET? I wouldn’t know). The code below pretty much illustrates the canonical approach: loop over available windows, find their process id, and compare against the process id you first thought of. Since a process could have multiple visible top-level windows, I’ve allowed for a list of HWNDs but this is probably overkill.
import subprocess import time import win32con import win32gui from win32gui import IsWindowVisible, IsWindowEnabled import win32process def get_hwnds_for_pid (pid): def callback (hwnd, hwnds): if IsWindowVisible (hwnd) and IsWindowEnabled (hwnd): _, found_pid = win32process.GetWindowThreadProcessId (hwnd) if found_pid == pid: hwnds.append (hwnd) return True hwnds = [] win32gui.EnumWindows (callback, hwnds) return hwnds if __name__ == '__main__': notepad = subprocess.Popen ([r"notepad.exe"]) # # sleep to give the window time to appear # time.sleep (2.0) for hwnd in get_hwnds_for_pid (notepad.pid): print hwnd, "=>", win32gui.GetWindowText (hwnd) win32gui.SendMessage (hwnd, win32con.WM_CLOSE, 0, 0)