Python如何向未置于顶层的特定程序后台发送键盘按键
Windows平台Python后台定向发送按键实现
要实现不激活目标窗口、不抢占当前输入焦点、按键仅发送给指定程序的需求,不要用全局输入模拟类库,直接调用Windows API向目标窗口消息队列异步投递按键消息即可,全程你可以正常操作其他软件,输入不会串到当前工作的窗口。
该方案仅适用于Windows系统,macOS/Linux的后台输入机制不同,不适用以下代码。
前置依赖
安装调用Win32接口需要的库:pip install pywin32
实现逻辑
- 先通过窗口标题匹配拿到目标程序的窗口句柄(HWND),窗口最小化、在后台都能正常获取,不需要置顶
- 用
PostMessage接口异步投递按键消息,不要用SendMessage:前者把消息扔到目标窗口队列就返回,不会阻塞你的操作;后者会等窗口处理完消息才返回,容易卡 - 普通可打印字符直接发
WM_CHAR消息,不用自己处理大小写、shift组合;功能键(回车、方向键、F区按键、退格等)发WM_KEYDOWN和WM_KEYUP配对消息即可
可直接复用的代码
import win32gui import win32con import time def get_target_hwnd(title_keyword: str) -> int: """根据窗口标题关键词查找目标窗口句柄""" hwnd_list = [] def callback(hwnd, _): if win32gui.IsWindowVisible(hwnd): current_title = win32gui.GetWindowText(hwnd) if title_keyword in current_title: hwnd_list.append(hwnd) win32gui.EnumWindows(callback, None) if not hwnd_list: raise RuntimeError(f"没找到标题包含「{title_keyword}」的窗口,请确认程序已经启动") return hwnd_list[0] def press_key(hwnd: int, vk_code: int): """发送通用虚拟按键,适合功能键""" win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, vk_code, 0) time.sleep(0.05) win32gui.PostMessage(hwnd, win32con.WM_KEYUP, vk_code, 0) def input_char(hwnd: int, char: str): """发送单个可打印字符,支持字母、数字、符号""" if len(char) != 1: raise ValueError("单次只能输入单个字符") win32gui.PostMessage(hwnd, win32con.WM_CHAR, ord(char), 0) time.sleep(0.05) if __name__ == "__main__": # 示例:替换成你自己目标程序的窗口标题关键词,比如微信是"微信",记事本是"记事本" target_hwnd = get_target_hwnd("记事本") print(f"匹配到目标窗口句柄:{target_hwnd},3秒后开始发送按键,期间你可以随意切到其他窗口操作") time.sleep(3) # 测试输入字符串+回车 test_content = "后台按键测试123" for c in test_content: input_char(target_hwnd, c) # 发送回车 press_key(target_hwnd, win32con.VK_RETURN)
注意事项
- 常规Win32桌面程序(记事本、资源管理器、大部分老端游、传统桌面软件)都能正常响应上面的消息;部分用DirectX绘制的全屏游戏、UWP应用不响应标准窗口消息,这类场景需要额外带扫描码参数投递,或者用驱动级输入方案
- 别用
pyautogui、keyboard这类全局模拟库,这类库是往系统全局输入队列插事件,必须把目标窗口切到最前面才能接收到,你操作其他软件的时候输入会直接串到你当前用的窗口里,完全不符合需求 - 按键消息之间留30-100ms的间隔,部分程序处理消息速度慢,间隔太短会丢按键
内容的提问来源于stack exchange,提问作者lordmord01
相关产品推荐
相关产品推荐

