Windows平台Python实现禁用实体键鼠(保留ESC键)、仅允许虚拟键鼠输入方案问询
嘿,这个需求刚好能在Windows上用Python实现,我给你梳理下具体的方案和代码,一步步来:
核心思路拆解
要实现这个需求,我们得用到Windows的底层钩子(Hook)来拦截键鼠输入,同时区分实体输入和虚拟输入(比如你用pyautogui模拟的操作)。另外还要全局监听ESC键,用来切换程序的暂停/运行状态。Python里可以用pywin32库调用Windows API来实现钩子,搭配你已经在使用的pyautogui来完成Acrobat的自动化操作。
步骤1:安装依赖
首先得装好需要的Python库,打开命令行运行:
pip install pywin32 pyautogui
pywin32用来做系统钩子和API调用,pyautogui就是你用来操作Acrobat的工具,完美兼容。
步骤2:完整代码实现
下面是整合了所有功能的代码,我加了详细注释,你可以直接替换里面的Acrobat自动化逻辑:
import win32api import win32con import win32gui import win32hook import pyautogui import threading import time # 全局状态:True=程序运行中,False=程序暂停 is_running = True # 标记当前是否是我们自己的虚拟输入(防止拦截pyautogui的操作) is_virtual_input = False def mark_virtual_input(status): """在执行pyautogui操作前调用,标记为虚拟输入""" global is_virtual_input is_virtual_input = status def keyboard_hook_callback(nCode, wParam, lParam): """全局键盘钩子回调函数""" global is_running, is_virtual_input # 只处理有效的键盘按下事件 if nCode >= 0 and wParam in [win32con.WM_KEYDOWN, win32con.WM_SYSKEYDOWN]: key_code = lParam[0] # 处理ESC键:切换程序运行/暂停状态 if key_code == win32con.VK_ESCAPE: is_running = not is_running print(f"\r程序已{'恢复运行' if is_running else '暂停'}", end="") # 放行ESC键,让系统也能收到(比如需要退出时) return win32hook.CallNextHookEx(None, nCode, wParam, lParam) # 规则:虚拟输入放行,实体输入拦截(除了ESC) if is_virtual_input: return win32hook.CallNextHookEx(None, nCode, wParam, lParam) else: # 返回1表示拦截该键盘事件 return 1 # 其他情况传递给下一个钩子 return win32hook.CallNextHookEx(None, nCode, wParam, lParam) def mouse_hook_callback(nCode, wParam, lParam): """全局鼠标钩子回调函数""" global is_virtual_input if nCode >= 0: # 检查输入是否是系统标记的虚拟输入(LLMHF_INJECTED标志) # 同时结合我们自己的标记,确保所有合法虚拟输入都放行 is_system_virtual = (lParam[3] & 0x00000001) != 0 if not is_system_virtual and not is_virtual_input: # 实体鼠标输入,直接拦截 return 1 return win32hook.CallNextHookEx(None, nCode, wParam, lParam) def install_global_hooks(): """安装全局键盘和鼠标钩子""" global keyboard_hook_handle, mouse_hook_handle # 安装低级键盘钩子(WH_KEYBOARD_LL) keyboard_hook_handle = win32hook.SetWindowsHookEx( win32con.WH_KEYBOARD_LL, keyboard_hook_callback, win32api.GetModuleHandle(None), 0 ) # 安装低级鼠标钩子(WH_MOUSE_LL) mouse_hook_handle = win32hook.SetWindowsHookEx( win32con.WH_MOUSE_LL, mouse_hook_callback, win32api.GetModuleHandle(None), 0 ) if not keyboard_hook_handle or not mouse_hook_handle: raise Exception("钩子安装失败,请确保以管理员权限运行程序!") def uninstall_global_hooks(): """程序退出时卸载钩子,避免系统异常""" if keyboard_hook_handle: win32hook.UnhookWindowsHookEx(keyboard_hook_handle) if mouse_hook_handle: win32hook.UnhookWindowsHookEx(mouse_hook_handle) def acrobat_auto_task(): """你的Acrobat自动化任务,替换成自己的逻辑即可""" global is_running while True: if is_running: print("\r正在执行Acrobat自动化操作...", end="") # ---------------------- # 这里替换成你的Acrobat操作代码 # 示例:启动Acrobat、点击按钮、输入文本 # ---------------------- # 执行虚拟操作前,标记为虚拟输入 mark_virtual_input(True) # 示例操作:点击某个按钮 # pyautogui.click(x=200, y=300) # 示例操作:输入文本 # pyautogui.typewrite("需要输入的内容") # 操作完成后,重置标记 mark_virtual_input(False) time.sleep(2) # 根据实际操作间隔调整 else: print("\r程序已暂停,按ESC键恢复运行...", end="") time.sleep(1) if __name__ == "__main__": try: print("程序启动成功!按ESC键切换暂停/运行状态") print("⚠️ 注意:必须以管理员权限运行此程序,否则钩子无法生效!") # 安装全局钩子 install_global_hooks() # 启动自动化任务线程(避免阻塞钩子消息处理) auto_thread = threading.Thread(target=acrobat_auto_task, daemon=True) auto_thread.start() # 保持主程序运行,处理系统钩子消息 while True: win32gui.PumpWaitingMessages() time.sleep(0.1) except KeyboardInterrupt: print("\n程序即将退出...") finally: # 卸载钩子,清理资源 uninstall_global_hooks() print("钩子已卸载,程序正常退出")
关键细节说明
- 管理员权限:必须右键以管理员身份运行Python脚本,否则全局钩子无法安装成功,因为系统需要权限来拦截全局输入。
- 虚拟输入识别:我们用了两种方式判断虚拟输入:自己维护的
is_virtual_input标记(确保pyautogui的操作不被拦截),以及系统自带的LLMHF_INJECTED标志(识别其他合法虚拟输入)。 - ESC键全局监听:不管程序是否处于前台,按下ESC都会切换运行状态,避免用户误操作时无法暂停。
- 线程分离:把自动化任务放到单独线程,防止主程序被阻塞,确保钩子能正常处理系统消息。
测试建议
- 先注释掉键盘和鼠标钩子的拦截逻辑(比如把
return 1改成return win32hook.CallNextHookEx(...)),测试ESC键和Acrobat自动化逻辑是否正常。 - 确认正常后,再开启拦截功能,测试实体键鼠是否被屏蔽,虚拟输入是否正常工作。
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

