Windows 10下使用subprocess.Popen后如何获取进程的handle(hWnd)?
在Windows 10中通过subprocess.Popen获取进程的窗口句柄(hWnd)
要实现这个需求,核心是通过Windows API根据进程PID查找对应的窗口句柄。以下是两种可行方案:
方案一:使用pywin32库(更简洁)
首先安装依赖:
pip install pywin32
示例代码:
import subprocess import win32gui import win32process import time def get_hwnd_by_pid(pid): hwnd_list = [] def callback(hwnd, extra): # 获取窗口所属进程的PID _, window_pid = win32process.GetWindowThreadProcessId(hwnd) if window_pid == extra and win32gui.IsWindowVisible(hwnd): hwnd_list.append(hwnd) # 枚举所有顶层窗口 win32gui.EnumWindows(callback, pid) return hwnd_list # 启动目标进程 proc = subprocess.Popen("notepad.exe") # 等待窗口创建(根据程序启动速度调整等待时间) time.sleep(1) # 获取窗口句柄列表 hwnds = get_hwnd_by_pid(proc.pid) if hwnds: print(f"找到窗口句柄: {hwnds}") # 若有多个窗口,可通过窗口标题进一步过滤 target_hwnd = next((hwnd for hwnd in hwnds if win32gui.GetWindowText(hwnd) == "无标题 - 记事本"), None) if target_hwnd: print(f"目标窗口句柄: {target_hwnd}") else: print("未找到对应窗口句柄")
方案二:使用ctypes(无需额外安装库)
直接调用Windows原生API,无需安装第三方库:
import subprocess import ctypes import time from ctypes import wintypes user32 = ctypes.WinDLL('user32', use_last_error=True) kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) # 定义Windows API的参数和返回值类型 user32.EnumWindows.argtypes = [ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM), wintypes.LPARAM] user32.GetWindowThreadProcessId.argtypes = [wintypes.HWND, wintypes.LPDWORD] user32.IsWindowVisible.argtypes = [wintypes.HWND] user32.IsWindowVisible.restype = wintypes.BOOL def get_hwnd_by_pid(pid): hwnd_list = [] # 定义回调函数类型 WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM) def callback(hwnd, lparam): window_pid = wintypes.DWORD() user32.GetWindowThreadProcessId(hwnd, ctypes.byref(window_pid)) if window_pid.value == lparam and user32.IsWindowVisible(hwnd): hwnd_list.append(hwnd) return True # 转换回调函数为C可调用类型 enum_callback = WNDENUMPROC(callback) user32.EnumWindows(enum_callback, pid) return hwnd_list # 启动进程 proc = subprocess.Popen("notepad.exe") time.sleep(1) hwnds = get_hwnd_by_pid(proc.pid) if hwnds: print(f"找到窗口句柄: {hwnds}") else: print("未找到对应窗口句柄")
注意事项
- 进程启动后需要短暂等待,确保窗口已创建完成,否则可能找不到句柄。
- 部分进程可能没有可视化窗口(如后台服务),这类进程无法获取hWnd。
- 单个进程可能对应多个窗口,可通过
win32gui.GetWindowText(hwnd)(或ctypes的user32.GetWindowTextW)获取窗口标题,进一步筛选目标窗口。
内容的提问来源于stack exchange,提问作者Zxd2025
相关产品推荐
相关产品推荐

