使用SendMessage来实现两个AHK脚本进程之间的通信,基于 Windows 的 WM_COPYDATA 消息机制,用来在进程间传递字符串信息。
因为AHK没有多进程模型和管理功能,缺少对进程之间的 数据交换、资源共享、同步机制(如锁、事件、条件变量等)等功能,所以AHK更加适合开多进程做不同的任务。AHK的SendMessage通信是性价比最高的方法,底部有个最精简的通信函数模板供大家自定义通信和调用逻辑。
另一个精简但不能通信的多进程实现:多进程代替多线程函数 – 精简版
另一个可以共享变量和库调用的多进程,但执行效率不如SendMessage:共享对象的多进程库
先运行接收端.ahk,再运行发送端.ahk测试【需要互相通信就两端都创建唯一隐藏窗口】
接收端.ahk
; 先运行接收端.ahk,再运行发送端.ahk测试【需要互相通信就两端都创建唯一隐藏窗口】 Gui Gui_Label_Gui: Show, Hide, <<接收端的唯一隐藏窗口名>> OnMessage(0x4a, "ExecReceive_WM_COPYDATA") return ; 更多详见帮助文档:https://wyagd001.github.io/zh-cn/docs/lib/OnMessage.htm ; 接收字符串后保存在变量名为"收到的字符串",以供调用 ExecReceive_WM_COPYDATA(wParam, lParam) { Global 收到的字符串 := StrGet(NumGet(lParam + 2*A_PtrSize)) Try Gosub ExecReturn%wParam% Return true } ; ExecSend的参3不带标签,就默认向主进程发送信息,接收信息后跳转到ExecReturn0【默认为"0"】 ExecReturn0: ToolTip %收到的字符串% Return ; ExecSend的参数3设置为2时,进入这个ExecReturn2标签 ExecReturn2: ExitApp Return
发送端.ahk
; 先运行接收端.ahk,再运行发送端.ahk测试【需要互相通信就两端都创建唯一隐藏窗口】 ExecSend("发送端发送的字符串 - 并延时2秒", "<<接收端的唯一隐藏窗口名>>", 0) Sleep 2000 ExecSend("关闭接收进程的示例", "<<接收端的唯一隐藏窗口名>>", 2) return ; 更多详见帮助文档:https://wyagd001.github.io/zh-cn/docs/lib/OnMessage.htm ExecSend(StringToSend, Label="WinTitle", flag=0) { VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0) , NumPut((StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1), CopyDataStruct, A_PtrSize) , NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize) DetectHiddenWindows % ("On", DHW:=A_DetectHiddenWindows) WinGet, NewPID, PID, %Label% ahk_class AutoHotkeyGUI SendMessage, 0x4a, flag, &CopyDataStruct,, ahk_pid %NewPID% ahk_class AutoHotkey DetectHiddenWindows %DHW% Return ErrorLevel }
精简的SendMessage兼容汉字通信函数模板.ahk
; 最精简的SendMessage汉字通信函数,方便制作自己的进程通信 Gui Show, Hide, 通信隐藏识别标题 OnMessage(0x4a, "ExecReceive_WM_COPYDATA") Return F1::ExecSend("发送内容可以是中文", "通信隐藏识别标题") ExecSend(StringToSend, Title="ScriptTitle", wParam=0) { VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0) , NumPut((StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1), CopyDataStruct, A_PtrSize) , NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize) Return DllCall("SendMessageW", "Ptr", DllCall("FindWindowW", "Str", "AutoHotkeyGUI", "Str", Title, "Ptr"), "UInt", 0x4A, "Ptr", wParam, "Ptr", &CopyDataStruct, "Ptr") } ; 接收字符串后保存在变量名为"收到的字符串",以供调用 ExecReceive_WM_COPYDATA(wParam, lParam) { Global 收到的字符串 := StrGet(NumGet(lParam + 2*A_PtrSize)) MsgBox % 收到的字符串 "`n`nwParam只能接收数字:" wParam ; Gosub ExecReturn%wParam% ; 也可以做一个外部标签跳转执行你的流程 Return true }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)