190508-319413

常用功能

激活应用

1
2
3
tell application "Terminal"
activate
end tell

延时

1
delay 1 -- 1秒

打印log

1
2
log _filename
log _extension

image-20190822134107227

路径转换

注意:以下代码可在顶层运行,不必在 finder 中。

转换苹果风格(:)为UNIX路径(/)

1
2
set a to "Macintosh HD:usr:local:bin:" 
set p to POSIX path of a

转换UNIX路径(/)为苹果风格(:)

1
2
3
set p to "/usr/local/bin/" 
set a to POSIX file p -- file "Macintosh HD:usr:local:bin:"
set a to POSIX file p as string -- "Macintosh HD:usr:local:bin:"

Alias类型(替身)

1
2
set a to alias "Macintosh HD:usr:local:bin:" 
set p to POSIX path of a

file类型(链接)

1
2
set a to file "Macintosh HD:usr:local:bin:" 
set p to POSIX path of a

用户目录路径

1
tell application "Finder" to open (POSIX path of (path to home folder)) & "download/Getting Started.pdf" as POSIX file

脚本所在目录(作为相对路径)

1
2
--"::"可将路径转换为上一级
set dirPath to (alias ((path to me as text) & "::") as text) & "lib.applescript"

获取文件内容

1
2
read alias mdPath as «class utf8»
set mdText to result

文件读写

1
2
3
4
set qnlistFile to open for access qnlistFile with write permission --打开写入许可
set eof qnlistFile to 0 --内容长度为0,完全覆盖
write qulist to qnlistFile as «class utf8» --写入文件
close access qnlistFile --关闭文件

Finder 调用

获取文件列表

1
2
3
4
5
6
7
set folderPath to alias "Macintosh HD:Users:fwk:Downloads:test:"
tell application "Finder"
set imgFile to every file of folderPath whose name does not start with "_" --排除字符_
repeat with i in imgFile
duplicate (contents of i) to imgUpload with replacing --复制文件到 imgUpload
end repeat
end tell
1
2
3
4
--名称不包含指定字符
tell application "Finder"
set imgFile to every file of alias folderPath whose name does not contain ".txt"
end tell

获取文件扩展名和整个文件名

1
2
3
4
5
6
7
8
9
10
11
12
set mdPath to alias "Macintosh HD:Users:fwk:test.txt"
tell application "Finder"
set _extension to name extension of mdPath --txt 扩展名
set _filename to name of mdPath --test.txt 文件名+扩展名
end tell

--获取不含后缀的文件名
tell application "Finder"
set {_filename, _extension} to {name, name extension} of mdPath
set _length to (count _filename) - (count _extension) - 1
set mdName to text 1 thru _length of _filename --去掉后缀
end tell

获取文件所在目录的路径

1
2
3
4
set filePath to alias "Macintosh HD:Users:fwk:Downloads:file.pdf"
tell application "Finder"
set folderPath to container of filePath as alias
end tell

路径拼接

1
2
3
set folderPath to alias "Macintosh HD:Users:fwk:Downloads:"
set f to folderPath as text
set filePath to f & "file.pdf" as alias

文件重命名

1
2
3
4
set mdPath to alias "Macintosh HD:Users:fwk:Downloads:aa.png"  --路径需为 alias 类型
tell application "Finder"
set name of mdPath to "bb.md"
end tell

判断路径是否存在

1
exists alias "Macintosh HD:Users:fwk:abcdef" --false

文件复制(有同名会替换)

1
2
3
4
5
6
7
8
9
--推荐,复制并替换,目标文件夹不存在时会自动创建,复制过程中不仅能保留源文件(夹)的属性与权限,还能保留源文件的资源分支结构和文件夹的源结构。
tell application "System Events"
do shell script "ditto /Users/fwk/a.pdf /Users" user name "fwk" password "xxx" with administrator privileges
end tell

--复制并替换,但不能创建文件夹
tell application "System Events"
do shell script "cp -R /Users/fwk/a.pdf /Users" user name "fwk" password "xxx" with administrator privileges
end tell
1
2
3
4
5
6
7
8
9
10
--复制文件
tell application "Finder"
duplicate file "Macintosh HD:Users:user:Desktop:Test Folder 1:test.doc" to folder "Macintosh HD:Users:user:Desktop:Test Folder 2" with replacing
end tell
--不想替换的去掉with replacing

--复制文件夹
tell application "Finder"
duplicate folder "Macintosh HD:Users:fwk:Library:Application Support:Code:User" to folder "data:software:!mac:备份:vscode" with replacing
end tell

复制多个文件

1
2
3
repeat with i in imgFile
duplicate (contents of i) to imgPath
end repeat

文件移动

1
set theFile to (move theFile to desktop) --移动文件并返回移动后的位置

新建文件夹

1
2
3
tell application "Finder"
make new folder at alias "Macintosh HD:Users:user:Desktop:" with properties {name:"Test Folder 2"}
end tell

打开文件夹

1
2
3
4
tell application "Path Finder"
activate
open "Macintosh HD:Users:user:Desktop:"
end tell

Finder 选中的文件

1
2
3
4
tell application "Finder"
set itemlist to the selection
set theFile to item 1 of itemlist
end tell

文本编辑

文本替换方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
set mdText to replaceText(oldImgName, newImgName, mdText)

--定义文本替换方法
on replaceText(find, replace, subject)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set subject to text items of subject

set text item delimiters of AppleScript to replace
set subject to "" & subject
set text item delimiters of AppleScript to prevTIDs

return subject
end replaceText
1
2
3
4
5
6
7
8
9
--未验证
on Replace(repalceString, oldString, newString)
tell application "System Events"
set AppleScript's text item delimiters to oldString
set aa to every text item of repalceString
set AppleScript's text item delimiters to newString
set bb to aa as string
end tell
end Replace

捕捉错误

1
2
3
4
5
6
7
try
set x to 1 / 0
on error the error_message number the error_number
display alert "错误:" & the error_number & " " & the error_message
end try
--error_message记录了出错信息,是一个String类型。
--error_number记录了错误代号,是一个number类型。

弹框

display dialog

1
display dialog "ok"

列表选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--简单列表选择
choose from list {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

--增加标题
with title "Calendar Picker"
--增加说明
with prompt "Choose one or more days"
--自定义按钮
OK button name "These Days" cancel button name "No Days"
--默认选项
default items {"Monday"}
--支持多选,按cmd键或shift键
with multiple selections allowed

--结果:得到复杂列表选择
choose from list {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} with title "Calendar Picker" with prompt "Choose one or more days" OK button name "These Days" cancel button name "No Days" default items {"Monday"} with multiple selections allowed

完整功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 弹框完整功能
set DIALOG_1 to (display dialog "Enter password for " & return & "" & ¬
quoted form of "This is not my script, credits to maker." with title "LiveJournal Post Event" with icon stop ¬
default answer "HaHa" buttons {"Continue…", "okay"} ¬
default button 1 ¬
giving up after 10 with hidden answer)
set my_pass to text returned of DIALOG_1
set button to button returned of DIALOG_1
display dialog "hello, this is the pasword: " & my_pass
display dialog "hello, you know that " & button & " is the button returned of the first window?"
set optionList to {"one", "two", "three", "4", "jefeijs", "3;32.32", "I DON't want this"}
set hey to choose from list optionList with prompt "This is not mine to:"
set lol to hey
if hey is false then
error number -128 (* user cancelled *)
else
set hey to hey's item 1 (* extract choice from list *)
end if
if lol is {"I DON't want this"} then
display dialog "ok"
else
display dialog "You choose: " & hey & " !"
end if

####

数据类型

变量

1
2
3
4
5
6
7
8
9
10
11
12
-- 设值 
set someValue to "Apple"
set x to 10

-- 字符串转整型数字
set x to "10" as number

-- 取值
get someValue

--设为无值
set X to missing value

字符串处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
set str to "hello, world"

-- 获取字符串长度
set strLength to the length of "hello"

-- 截取第一到倒数第2个字符
text 1 thru -2 of str

-- 取最后一个字符
text -1 of str

-- 使用 & 连接字符串
set str to "hello," & " world"

-- 使用 \ 来转义
set str to "\"hello\""

-- 整型转字符串
set str to 10 as string

-- 把字符串转成字符数组:every character of
set strList to every character of "String"

-- 数字转 ASCII码
ASCII character 65
返回:A

-- ASCII 码转数字
ASCII number "A"
返回:65

-- 取出一段字符串在另一段字符串的位置
offset of "el" in "hello"
返回:2

-- 按字符分割字符串 :AppleScript's text item delimiters
set defaultDelimiters to AppleScript's text item delimiters (* 先保存默认字符分割符 *)
set AppleScript's text item delimiters to "," (* 使用 AppleScript's text item delimiters 来指定分割符 *)
set strList to every text item of "1,12,321,cdsa"
set AppleScript's text item delimiters to defaultDelimiters (* 分割完之后需要还原分割符 *)
get strList

-- 将数组按照指定分割符组成一段字符串
set defaultDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set restoredStr to {"hello", "world"} as string
set AppleScript's text item delimiters to defaultDelimiters
get restoredStr

Split方法

1
2
3
4
5
6
on Split(delimiter, splitString)
tell application "System Events"
set AppleScript's text item delimiters to delimiter
set aa to every text item of splitString
end tell
end Split

Contain

判断字符串A是否包含字符串B  

1
return “abc" contain "a"  --return true

list(数组)和 string 转换

1
2
3
4
5
set pdfName0 to "1hello.pdf"
set nameList0 to every character of pdfName0 --string分割为数组,
set listLength to the length of nameList0 --获取数组长度
set namelist to items 2 through listLength of nameList0 --去掉首字符
set pdfName to "" & namelist --数组转换为 string,结果的类型由&运算符之前的变量类型决定

list 数组

删除数组中指定序号的一项,通过递归实现

1
2
3
4
5
6
7
8
9
10
on removeNum(num, arr)
if arr is {} then
return {}
else if num is 1 then
return rest of arr
else
return {item 1 of arr} & removeNum(num - 1, rest of arr)
end if
end removeNum
removeNum(2, {"Mannie", "Moe", "Jack"}) --{"Mannie", "Jack"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
set list1 to {10, "value1", "value2"}

-- 获取数组长度:the length of 或 the count of
the length of list1

-- 使用 & 连接数组
set list2 to list1 & {"value4"}

-- 使用 & 连接数组和其他类型变量,& 左边的值的类型决定连接后的值的类型
get "valueX" & list1

(* 使用 item index of 获取 list 第 index 个元素,
若 index 为正数则从第一个向后第 index 个元素,
若 index 为负数则从最后一个向前第 index 个元素 *)
item 2 of list2

-- 更改数组元素
set item 2 of list2 to "value3"

-- 使用 the end of 为数组从末尾添加元素
set the end of list2 to "value5"

-- 使用 some item of 来随机获取 list2 中元素
set randomItem to some item of list2

-- 获取指定项
set firstItem to the item 1 of list2

-- 使用 the last item of 获取 list2 最后的元素, 同理可以使用 first、second 等
set lastItem to the last item of list2

-- 使用 items begin through end of 获取 list2 的子数组
set shotList to items 2 through 3 of list2

-- 使用 reverse of 反转数组
set reverseList to reverse of list2

-- 将变量转换成数组
set list3 to "value6" as list

数组过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--过滤字符串数组的注释项(开头为“--”)
on filter(arr)
script filterer
on filter(arr)
if arr = {} then return arr
if text 1 thru 2 of (item 1 of arr) ≠ "--" then
return {item 1 of arr} & filter(rest of arr)
else
return filter(rest of arr)
end if
end filter
end script
return filterer's filter(arr)
end filter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
--通用过滤,通过判断函数过滤
on filter(arr, judgeFunc)
script filterer
property judgement : judgeFunc
on filter(arr)
if arr = {} then return arr
if judgement(item 1 of arr) then
return {item 1 of arr} & filter(rest of arr)
else
return filter(rest of arr)
end if
end filter
end script
return filterer's filter(arr)
end filter
--判断函数
on isNumber(x)
return ((class of x) is in {real, integer, number})
end isNumber
filter({"hey", 1, "ho", 2, 3}, isNumber)

record 字典

1
2
3
4
5
6
7
8
9
10
11
12
13
set record1 to {key1: "value1", key2: "value2"}

-- 使用 the length/count 获取字典 key/value 対数目
get the count of record1

-- 使用 the key of record 为字典改变值
set the key1 of record1 to "changedValue"

-- 使用 the key of record 根据 key 获取字典值
get the key1 of record1

-- 使用 the items of 获取由字典所有值组成的数组
get the items of record1

record 转 数组

1
2
3
set record1 to {key1:"value1", key2:"value2"}
copy the result as list to {text_returned, button_pressed}
get text_returned -- 结果value1

日期时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
set d to do shell script "date '+%Y-%m-%d %H:%M:%S'"  --获取当前时间,如:2018-10-20 12:17:35

The date formatters are:
%Y 年4位 如:2018
%y 年2位 如:18
%B 月英文全称,如:October
%b 月英文 简称,如:Oct
%m 月2位 如:09
%-m 月无0 如:9
&d 日
%n 换行
%H 时
%M 分
%S 秒

流程控制

条件语句

一般形式

1
2
3
4
5
6
7
if 条件 then  
...
else if 条件 then
...
else
...
end if

至简形式

1
2
-- 都写在一行
if 条件 then ...

数字比较

  • = 等于
  • > 大于
  • < 小于
  • >= 大于等于
  • <= 小于等于
  • /= 不等于

无值

  • a = missing value –没有值也没有class
  • a= null –为null class的对象
  • if a is in {“”,missing value}

字符串比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-- str1 是否以 str2 开头
str1 begins with (或者 starts with) str2

-- str1 是否不以 str2 开头
str1 does not start with str2

-- str2 是否以 str2 结尾
str1 ends with str2

-- str2 是否不以 str2 结尾
str1 does not end with str2

-- 是否一致
str1 is equal to str2

-- str1 是否在 str2 之前
str1 is comes before str2

-- str1 是否在 str2 之后
str1 is comes after str2

-- 包含 str1 是否在 str2 里
str1 is in str2

-- str1 是否不在 str2 里
str1 is not in str2

-- str1 是否包含 str2
str1 contains str2

-- str1 是否不包含 str2
str1 does not contain str2

循环语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-- repeat x times
set num to 0
repeat 3 times
set num to num + 1
end repeat

-- repeat with 计数变量 from 起始值 to 结束值 by 增长值
-- by 增长值 缺省为1
set num to 0
set startValue to 0
set endValue to 10
set stepValue to 2
repeat with temp from startValue to endValue by stepValue
set num to num + temp
end repeat

-- repeat while 循环条件
set num to 0
repeat while num /= 10
set num to num + 1
end repeat

-- repeat until 循环结束条件
set num to 0
repeat until num = 10
set num to num + 1
end repeat

-- repeat with 单个元素 in 数组
set num to 0
repeat with temp in {1, 2, 3}
set num to num + temp
end repeat

终止执行

该错误码为用户取消执行,可用于终止程序的执行

1
error number -128

句柄(函数)

1
2
3
4
5
6
-- 带参数和返回值的函数
on charactersOfStr(str)
return every character of str
end charactersOfStr

get charactersOfStr("hello,world")

运行句柄 on run

  • 每个脚本对象都有且只能有一个运行句柄
  • 显式运行句柄,外部不能再放代码,脚本和句柄定义本身不是代码,其内部才是代码
  • 句柄中不能定义句柄;
  • 隐式运行句柄时,在顶层定义的句柄其实是在运行句柄外;
1
2
--隐式运行句柄
display dialog a
1
2
3
4
5
6
7
8
9
10
--显式运行句柄,外部不能再放代码,(注意,脚本和句柄定义不是代码)
on run{a}
display dialog a
end run
on doany()
display dialog "bb"
end doany
script s
display dialog "cc"
end script
1
2
3
4
5
set a to 1 --隐式运行句柄内
on doany() --隐式运行句柄外
display dialog "bb"
end doany
set b to 2 --隐式运行句柄内

调用脚本

调用的脚本后缀必须是.scpt(已编译),不支持调用.applescript(未编译),可采用第三方库来调用

调用

1
2
3
set lib to load script alias "Macintosh HD:Users:fwk:Library:Mobile Documents:com~apple~CloudDocs:applescript:lib.scpt" 
set findVal to lib's findVal --lib中定义的函数
findVal(".el-dialog__wrapper", 0, 0, 0) -- 使用函数
1
2
--相对脚本所在目录引用
set lib to load script alias ((alias ((path to me as text) & "::") as text) & "lib.scpt")
1
2
3
4
5
6
7
8
9
-- 如果要在其他应用内调用本文件中的 Handler,要在调用后加 of me 来指定该 Handler 所在文件
on warnFunc()
display dialog "将要清空废纸篓" buttons {"OK"} default button "OK"
return button returned of result as string
end warnFunc

tell application "Finder"
if warnFunc() of me is equal to "OK" then empty the trash
end tell

执行脚本

用try包裹,并在调用的脚本中使用error number -128,可终止脚本执行,实现按条件跳过执行,继续回到当前脚本继续执行。

1
2
3
try
run script alias "Macintosh HD:Users:fwk:dosomething.scpt"
end try

带参数执行

1
2
3
4
5
6
7
8
--脚本myScript.scpt
on run {A, B} --带参数后该脚本不能自己执行,会提示参数不匹配
display dialog A & space & B buttons {"OK"} default button "OK"
end run

--执行脚本
set xxx to (path to desktop as text) & "myScript.scpt" as alias
run script xxx with parameters {"one", "two"}

界面创建-xcode

AppleScriptObjC

定义

1
2
3
--IBOutletd定义
property myField: missing value
property myButton: missing value
Objective-C AppleScript
@interface MyClass : NSObject { script MyClass
property parent: class “NSObject”
int myProperty;
IBOutlet NSTextField myField;
}
IBOutlet @property (retain) NSButton
myButton;
property myProperty: 0
property myField: missing value
property myButton: missing value
@end
@implementation MyClass
- (IBAction) myAction:(id) object { on myAction_(object)
[object method];
[object method:param];
[object methodWithArg1:p1 arg2:p2];
object’s method()
object’s method_(param)
object’s methodWithArg1_arg2_(p1, p2)
[object property]; object.property; object’s property()
object’s property
}
@end
end myAction_
end script

标识符冲突

当cocoa与AppleScript同时拥有相同的标识符时会出现冲突,需要用||包裹来表示是AppleScript的标识符,如:

1
2
tell myColor to |set|() --NSColor has a set method for setting the current drawing color
get myWindow's |bounds| --NSWindow has a bounds property

设值

1
2
3
4
5
6
--修改文本内容
theLabel's setStringValue_("abc")
--修改输入框浮点值
celsius_readout's setFloatValue_((temp_value as degrees Celsius) as real)
--设置元素是否隐藏,对应view中的hidden属性,隐藏:yes,显示:no
theLabel's setHidden_(yes)

取值

1
2
3
4
5
6
7
8
--下拉菜单的当前选项
set a to (thePopup's titleOfSelectedItem()) as string
--输入框字符值
set a to theInputField's stringValue()
--输入框浮点值
set a to theInputField's floatValue()
--元素的是否隐藏,隐藏:1,显示:0
theLabel's isHidden
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--案例
script Temperature_ConverterAppDelegate
property input_field : missing value
property unit_type_popup : missing value
property fahrenheit_readout : missing value
property celsius_readout : missing value
property kelvin_readout : missing value
on calculateTemps_(sender)
set the unit_type to (unit_type_popup's titleOfSelectedItem()) as string
set the input_amount to input_field's floatValue()
if the unit_type is "Fahrenheit" then
set the temp_value to the input_amount as degrees Fahrenheit
else if the unit_type is "Celsius" then
set the temp_value to the input_amount as degrees Celsius
else if the unit_type is "Kelvin" then
set the temp_value to the input_amount as degrees Kelvin
end if
tell fahrenheit_readout to setFloatValue_((temp_value as degrees Fahrenheit) as real)
tell celsius_readout to setFloatValue_((temp_value as degrees Celsius) as real)
tell kelvin_readout to setFloatValue_((temp_value as degrees Kelvin) as real)
end calculateTemps_
end script

路径转换

Specifier Problem code Solutions
file file “Macintosh HD:Folder:File” target current application
alias alias “Macintosh HD:Folder:File” “Macintosh HD:Folder:File” as alias
POSIX file POSIX file “/Applications/Some.app” “/Applications/Some.app” as POSIX file
date date dateString set components of existing date, or current application’s date theDateString as date

如:

1
run script  "Macintosh HD:Users:fwk:Library:Mobile Documents:com~apple~CloudDocs:applescript:UI包更新和测试:try.applescript" as alias

界面关联

将程序中定义好的property变量与界面元素关联起来。在Delegate中点右键,找到变量拖到对应界面元素上即可:

image-20190925163527551

组件使用

NSScrollView

1
2
3
4
-- theInput 需连接到NSScrollView 的外层的ScrollView上
--获取输入框中的内容
log |string| of documentView of theInput
log inputPageID's documentView's |string| --写法不同,结果同上

应用调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--强制退出
tell application "TextEdit" to quit saving no

--新建文件
tell application "TextEdit"
make new document
activate
end tell

--新建窗口
tell application "Google Chrome"
make new window
activate
end tell

--使用指定应用打开文件或文件夹
tell application "Visual Studio Code"
open "Macintosh HD:Users:fwk:Downloads:style2"
end tell

Path Finder

1
2
3
4
5
tell application "Path Finder"
set selectlist to selection --所选文件list
--获得文件路径/Users/fwk/index.html
set _path to (get POSIX path of the item 1 of selectlist)
end tell

更多文件属性,替换上面的POSIX path 即可获得

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
--fsItem 类属性
extension hidden (boolean)
locked (boolean)
kind (text, r/o)
size (integer, r/o)
modification date (date)
name (text)
group privileges (text)
displayed name (text)
label index (integer)
everyones privileges (text)
disk (disk, r/o)
group (text)
owner (text)
information window (info window, r/o)
owner privileges (text)
creation date (date, r/o)
name extension (text, r/o)
physical size (integer, r/o)
container (container, r/o)
URL (text)
POSIX path (text)
path (text)

终端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tell application "Terminal"
-- 启动当前应用
activate
-- 判断当前是否有窗口打开
if (count of windows) is 0 then
-- 没有的话,告诉 "System Events" 做好准备
tell application "System Events"
-- 模拟按键 Command + N 新建一个窗口
keystroke "n" using {command down}
end tell
else
activate
end if

--命令
do script "qshell batchdelete -force blog-image /Users/fwk/qnlist.txt" in window [0]

end tell

路径有空格需在空格前加\,如aa bb,要写成aa\ bb

~/表示用户目录,如~/desktop 展开就是 /users/username/desktop

./source/_posts 相对目录

删除文件夹和文件
1
rm -r -f 文件夹名

Numbers

1
2
3
4
5
tell application "Numbers"
tell table 1 of sheet 3 of document 1
set the value of cell 1 of column "E" to 1000
end tell
end tell

批量压缩图片

1
2
3
4
5
6
7
8
9
10
11
12
--获取目录下的所有图片文件
tell application "Finder"
set imgFile to every file of alias imgPath whose name does not contain ".txt"
end tell
--压缩图片
tell application "Image Events"
repeat with i in imgFile
set img to open file ((contents of i) as text)
scale img to size 640
save img
close img
end repeat

chrome

打开链接

1
2
3
4
tell application "Google Chrome"
open location "https://google.com"
delay 0.1
end tell
1
2
tell application "Google Chrome" to get the title of the active tab of window 1 --获取页面标题
tell application "Google Chrome" to get the URL of the active tab of window 1 --获取页面链接

执行javascript

1
2
3
4
5
6
7
8
9
10
11
tell application "Google Chrome"
execute front window's active tab javascript "alert('example');"
end tell

--未验证
tell application "Google Chrome"
open location "https://google.com"
if (execute javascript "document.readyState") is "complete" then set pageLoaded to true
delay 3
display dialog pageLoaded as string
end tell

safari

1
2
3
4
5
6
7
8
9
10
11
12
tell application "Safari"
activate
open location "https://google.com" --新标签打开链接(已存在相同页面时不会在新标签打开)
tell window 1 to set current tab to (make new tab with properties {URL:"https://dnakit.ibroadlink.com/productInfo/#/DevProduct"}) --新标签打开链接
set URL of current tab of window 1 to "https://google.com" --在当前标签打开链接
set theURL to URL of current tab of window 1 --获得当前页面链接
close current tab of window 1 --关闭标签
tell front document
set ofTitle to name -- 获取页面标题
--set ofNote to URL -- 获取页面链接
end tell
end tell

safari 中的网页元素也支持applescript鼠标点击,详见鼠标通用点击

执行javascript

1
2
3
4
5
6
7
8
9
10
11
tell application "Safari"
activate
--点击页面元素
set theScript to "document.getElementsByClassName('column-link')[0].click();"
do JavaScript theScript in current tab of first window

--获取页面元素文本
set aa to do JavaScript "document.getElementsByClassName('ng-binding')[0].firstChild.nodeValue ;" in current tab of first window
end tell

tell application "Safari" to do JavaScript "alert('example')" in document 1

系统调用

获取界面元素

在 Xcode 菜单>Open develop tool > Accessibility Inspector,可查看界面元素的名称

获取前置APP 名称

1
2
3
tell application "System Events"
set frontAppProcess to name of first application process whose frontmost is true
end tell

获取前置窗口标题

1
2
3
4
5
6
7
8
9
tell application "System Events"
set frontAppProcess to first application process whose frontmost is true
set frontAppName to name of frontAppProcess
tell process frontAppName
if count of windows > 0 then
set window_name to name of front window
end if
end tell
end tell
1
2
3
4
5
6
7
8
tell application "System Events"
set frontAppProcess to first application process whose frontmost is true
end tell
tell frontAppProcess
if count of windows > 0 then
set window_name to name of front window
end if
end tell

判断窗口是否存在

1
2
3
4
5
6
7
8
9
tell application "Safari" to activate --打开 Safari
tell application "System Events"
tell process "Safari"
repeat until window 1 exists
-- 直到 Safari 应用的一个窗口存在之前,不停循环这段空语句
end repeat
-- 第一个窗口出现之后,继续要做的事……
end tell
end tell

鼠标点击

菜单栏鼠标点击

1
2
3
4
5
6
7
8
9
10
11
tell application "System Events" to tell (process 1 where frontmost is true)
click menu item "Minimize" of menu 1 of menu bar item "Window" of menu bar 1
end tell

tell application "System Events" to tell process "Finder"
set frontmost to true
tell menu bar item 3 of menu bar 1
click
click menu item "Open With" of menu 1
end tell
end tell

状态栏图标点击

1
2
3
4
5
6
7
tell application "System Events" to tell process "SystemUIServer"
set wifi_menu to (first menu bar item whose description contains "Wi-Fi") of menu bar 1
tell wifi_menu
click
click menu item "关闭 Wi-Fi" of menu 1
end tell
end tell

鼠标通用点击

获取界面路径构成
1
2
3
4
5
6
7
8
--在脚本编辑器中执行,通过click 坐标,获得坐标所在位置的界面路径构成
tell application "Safari"
activate
delay 0.5
tell application "System Events"
click at {1900, 270} -- 点击坐标所在位置,返回所点元素的界面元素构成
end tell
end tell
1
2
--结果返回界面路径如下:
text field 1 of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window "DNA Kit" of application process "Safari" of application "System Events"
通过界面路径进行点击
1
2
3
4
5
6
7
8
9
tell application "Safari" to activate --其实窗口不必在最前面,只要用tell process就能点击
delay 0.5
tell application "System Events"
tell process "Safari"
tell window "DNA Kit"
click text field 1 of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1
end tell
end tell
end tell
如何查看界面元素的坐标

打开Accessibility Inspector工具,点击右上方的目标工具,然后点击要查看的元素即可。

要注意的是屏幕坐标原点在左上角{0, 0},所以坐标值可以适当向右和向下取值,免得靠近边界可能点不到。

image-20190531161241234

触发按键

keystroke

主要用于字符输入,输入的是字符的对应按键,因此会受输入法影响;比如“!”在中文输入法下会变成“!”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tell application "System Events"
keystroke "v" using {command down, option down}
end tell

# 启动TextEdit并输入标准的“Hello world!”
tell application "System Events"
delay 0.5
keystroke space using command down
delay 0.5
keystroke "Text"
delay 0.5
keystroke "Edit"
delay 0.5
keystroke return
delay 1
keystroke "Hello world!"
end tell

部分键也能使用

1
2
3
keystroke return
keystroke space
keystroke tab
keycode:
1
2
3
tell application "System Events"
key code 53 using {command down, option down}
end tell

image-20190305170639458

0 0x00 ANSI_A
1 0x01 ANSI_S
2 0x02 ANSI_D
3 0x03 ANSI_F
4 0x04 ANSI_H
5 0x05 ANSI_G
6 0x06 ANSI_Z
7 0x07 ANSI_X
8 0x08 ANSI_C
9 0x09 ANSI_V
10 0x0A ISO_Section
11 0x0B ANSI_B
12 0x0C ANSI_Q
13 0x0D ANSI_W
14 0x0E ANSI_E
15 0x0F ANSI_R
16 0x10 ANSI_Y
17 0x11 ANSI_T
18 0x12 ANSI_1
19 0x13 ANSI_2
20 0x14 ANSI_3
21 0x15 ANSI_4
22 0x16 ANSI_6
23 0x17 ANSI_5
24 0x18 ANSI_Equal
25 0x19 ANSI_9
26 0x1A ANSI_7
27 0x1B ANSI_Minus
28 0x1C ANSI_8
29 0x1D ANSI_0
30 0x1E ANSI_RightBracket
31 0x1F ANSI_O
32 0x20 ANSI_U
33 0x21 ANSI_LeftBracket
34 0x22 ANSI_I
35 0x23 ANSI_P
36 0x24 Return
37 0x25 ANSI_L
38 0x26 ANSI_J
39 0x27 ANSI_Quote
40 0x28 ANSI_K
41 0x29 ANSI_Semicolon
42 0x2A ANSI_Backslash
43 0x2B ANSI_Comma
44 0x2C ANSI_Slash
45 0x2D ANSI_N
46 0x2E ANSI_M
47 0x2F ANSI_Period
48 0x30 Tab
49 0x31 Space
50 0x32 ANSI_Grave
51 0x33 Delete
53 0x35 Escape
55 0x37 Command
56 0x38 Shift
57 0x39 CapsLock
58 0x3A Option
59 0x3B Control
60 0x3C RightShift
61 0x3D RightOption
62 0x3E RightControl
63 0x3F Function
64 0x40 F17
65 0x41 ANSI_KeypadDecimal
67 0x43 ANSI_KeypadMultiply
69 0x45 ANSI_KeypadPlus
71 0x47 ANSI_KeypadClear
72 0x48 VolumeUp
73 0x49 VolumeDown
74 0x4A Mute
75 0x4B ANSI_KeypadDivide
76 0x4C ANSI_KeypadEnter
78 0x4E ANSI_KeypadMinus
79 0x4F F18
80 0x50 F19
81 0x51 ANSI_KeypadEquals
82 0x52 ANSI_Keypad0
83 0x53 ANSI_Keypad1
84 0x54 ANSI_Keypad2
85 0x55 ANSI_Keypad3
86 0x56 ANSI_Keypad4
87 0x57 ANSI_Keypad5
88 0x58 ANSI_Keypad6
89 0x59 ANSI_Keypad7
90 0x5A F20
91 0x5B ANSI_Keypad8
92 0x5C ANSI_Keypad9
93 0x5D JIS_Yen
94 0x5E JIS_Underscore
95 0x5F JIS_KeypadComma
96 0x60 F5
97 0x61 F6
98 0x62 F7
99 0x63 F3
100 0x64 F8
101 0x65 F9
102 0x66 JIS_Eisu
103 0x67 F11
104 0x68 JIS_Kana
105 0x69 F13
106 0x6A F16
107 0x6B F14
109 0x6D F10
111 0x6F F12
113 0x71 F15
114 0x72 Help
115 0x73 Home
116 0x74 PageUp
117 0x75 ForwardDelete
118 0x76 F4
119 0x77 End
120 0x78 F2
121 0x79 PageDown
122 0x7A F1
123 0x7B LeftArrow
124 0x7C RightArrow
125 0x7D DownArrow
126 0x7E UpArrow

剪贴板

1
2
3
4
set the clipboard to "hello"
set oldData to (get the clipboard as text)

set theData to (the clipboard as text) --输出结果相同,但数据不相等,猜测是clipboard对象

提示

对话框

1
display alert "This is an alert" --无按钮默认显示按钮好
1
2
3
4
5
6
7
8
display alert "This is an alert" buttons {"No", "Yes"}
if button returned of result = "No" then
display alert "No was clicked"
else
if button returned of result = "Yes" then
display alert "Yes was clicked"
end if
end if

消息通知

1
display notification " 通知内容"  --会自动消失

参考:Apple Script 从入门到放弃

常用函数

激活并等待

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
on waitActive(appName)
tell application appName to activate
tell application "System Events"
set frontAppProcess to name of first application process whose frontmost is true
set t to 0
repeat until frontAppProcess = appName
delay 0.01
set frontAppProcess to name of first application process whose frontmost is true
set t to t + 1
--超时0.5秒提示(实测执行不到,原因不详)
if t = 50 then
display alert "目标应用未激活: “" & appName & "”
当前为“" & frontAppProcess & "” 是否继续等待?" buttons {"终止", "继续等待"}
if button returned of result = "终止" then
error number -128
else
if button returned of result = "继续等待" then
set t to 0
end if
end if
end if
end repeat
delay 0.1
end tell
end waitActive