applescript 实现 macos 应用通信的关键是构建语义化指令链,依赖 apple events 协议;仅导出 sdef 词典的应用(如 safari、mail、textedit)原生支持,chrome 等需 system events 模拟操作,并通过状态反馈闭环验证。

AppleScript 实现 macOS 应用间交互通信,关键不是“写代码”,而是设计一条有起点、有中间动作、有终点的语义化指令链——每个环节都依赖 Apple Events 协议传递明确意图,而非底层数据搬运。
确认哪些应用能真正对话
只有导出 AppleScript 词典(sdef)的应用才支持原生通信。验证方法很直接:打开“脚本编辑器”,把目标 App(如 Safari、邮件、Numbers)拖进窗口,弹出词典就代表它可被“听懂”。Finder、Mail、Calendar、Notes、TextEdit、Terminal 都稳定支持;Safari 和 Numbers 支持程度高;Chrome、Slack、Figma 等 Electron 或 WebView 应用基本不响应 Apple Events,需改走 UI 脚本路径。
用 tell 块构建跨应用指令流
每个 tell application "X" 是一个独立上下文,只能对那个 App 发命令,但变量可在块之间传递。比如从 Safari 取标题、存文件、再让 TextEdit 打开:
tell application "Safari"
set pageTitle to name of front document
end tell
set tempFile to (path to desktop as text) & "title.txt"
do shell script "echo " & quoted form of pageTitle & " > " & quoted form of tempFile
tell application "TextEdit"
open file tempFile
end tell
注意三点:
-
quoted form of必须用于拼接 shell 命令,防止空格或特殊字符中断 - 路径要用
path to desktop as text这类系统路径表达式,别硬写/Users/xxx/Desktop/ - 不同
tell块之间不能直接传对象引用(如 document),只能传文本、数字、路径等基础类型
对非脚本化应用补位:System Events
当目标 App 没有词典(比如 Chrome 导出 PDF),就得靠 System Events 模拟点击。它本质是调用 macOS 辅助功能 API,操作前必须在「系统设置 → 隐私与安全性 → 辅助功能」里授权脚本编辑器:
tell application "Google Chrome" to activate
delay 0.5
tell application "System Events"
tell process "Google Chrome"
click menu item "导出为 PDF…" of menu "文件" of menu bar 1
delay 1
keystroke "save.pdf" -- 输入文件名
key code 36 -- 回车
end tell
end tell
这类操作脆弱但有效:菜单名变更、窗口未聚焦、延迟不足都会失败,所以 delay 和 activate 不可省略。
部署和使用军舰的 macOS Automator 自动化服务集合。包含 5 个实用工作流:PDF转JPG、PNG重命名并转JPG、图像拼接、解压RAR、顺序命名图像文件。一键安装所有服务到 ~/Library/Services/ 目录。使用场景:(1) "安装我的自动化服务",(2) "部署所有 Automato...
让通信结果可反馈、可判断
单纯“发指令”不算完整通信。加一层逻辑判断,才能形成闭环。例如检查邮件是否真发出了:
tell application "Mail"
set newMessage to make new outgoing message with properties {subject:"测试", content:"自动发送"}
tell newMessage
make new to recipient with properties {address:"test@example.com"}
send
end tell
end tell
-- 等待发送完成(Mail 发送后会移入“已发送”文件夹)
delay 2
tell application "Mail"
set sentCount to count of messages of mailbox "Sent" of account "iCloud"
if sentCount > 0 then
display notification "邮件已发出" with title "自动化完成"
end if
end tell
这里用“已发送邮件数量变化”作为通信成功的间接证据,比单纯 send 更可靠。
不复杂但容易忽略










