如何从运行中的Python脚本向运行中的AHK脚本传递变量?
从Python向AutoHotkey低延迟传递数据的解决方案
针对你需要从Python向AHK传递数据且延迟不超过30ms的需求,以下两种Windows原生IPC(进程间通信)方案均可满足要求,且不会干扰剪贴板或产生文件IO延迟:
方案1:WM_COPYDATA 消息(Windows原生,延迟极低)
WM_COPYDATA是Windows系统提供的专门用于进程间传递数据的消息,无需额外依赖,传递小数据时延迟通常在几毫秒内,完全符合你的要求。
Python 端代码(需安装 pywin32 库)
import win32api import win32gui import win32con import struct def send_to_ahk(data, window_title="AHK_Window"): # 找到AHK窗口(根据窗口标题,可替换为窗口类名) hwnd = win32gui.FindWindow(None, window_title) if not hwnd: print("未找到目标AHK窗口") return # 构造COPYDATASTRUCT结构体 data_bytes = data.encode('utf-8') cds = struct.pack('LLP', win32con.CF_UNICODETEXT, len(data_bytes)+1, data_bytes) # 发送WM_COPYDATA消息 win32api.SendMessage(hwnd, win32con.WM_COPYDATA, 0, cds) # 调用示例 send_to_ahk("从Python传递的数据", "My_AHK_Script_Window")
AutoHotkey 端代码
#Persistent OnMessage(0x004A, "OnCopyData") ; 0x004A 对应 WM_COPYDATA 消息 OnCopyData(wParam, lParam) { ; 解析传递的数据 data := StrGet(NumGet(lParam + A_PtrSize*2)) MsgBox, 收到Python传递的数据:%data% return true } ; 可选:设置窗口标题方便Python查找 WinSetTitle, %A_ScriptName%, , My_AHK_Script_Window
方案2:命名管道(Named Pipes)
Windows命名管道是一种高效的双向IPC机制,适合持续数据传递或稍大数据量的场景,延迟同样远低于30ms。
Python 端代码(需安装 pywin32 库)
import win32pipe import win32file def send_via_pipe(data): pipe_name = r'\\.\pipe\PythonToAHK_Pipe' try: # 连接到管道 handle = win32file.CreateFile( pipe_name, win32file.GENERIC_WRITE, 0, None, win32file.OPEN_EXISTING, 0, None ) # 写入数据 win32file.WriteFile(handle, data.encode('utf-8')) win32file.CloseHandle(handle) except Exception as e: print(f"管道发送失败:{e}") # 调用示例 send_via_pipe("通过命名管道传递的数据")
AutoHotkey 端代码
#Persistent pipe_name := "\\.\pipe\PythonToAHK_Pipe" ; 创建并监听管道 PipeListen() { global pipe_name while true { hPipe := DllCall("CreateNamedPipe", "Str", pipe_name, "UInt", 0x00000003, "UInt", 0, "UInt", 255, "UInt", 4096, "UInt", 4096, "UInt", 0, "Ptr", 0) if hPipe = -1 { Sleep, 100 continue } ; 等待连接 if DllCall("ConnectNamedPipe", "Ptr", hPipe, "Ptr", 0) { ; 读取数据 VarSetCapacity(buffer, 4096, 0) DllCall("ReadFile", "Ptr", hPipe, "Ptr", &buffer, "UInt", 4096, "Ptr", &bytes_read, "Ptr", 0) data := StrGet(&buffer, bytes_read, "UTF-8") MsgBox, 收到管道数据:%data% } DllCall("CloseHandle", "Ptr", hPipe) } } ; 启动监听 SetTimer, PipeListen, -1
方案对比
- WM_COPYDATA:实现简单,适合单次小数据传递,无需维持连接,延迟最低。
- 命名管道:支持双向通信,适合持续数据交互,可传递更大数据量,延迟同样达标。
两种方案的实际测试延迟均在10ms以内,完全满足你不超过30ms的要求。
内容的提问来源于stack exchange,提问作者John Keyberg
相关产品推荐
相关产品推荐

