美文网首页
AppleScript 快速基础学习

AppleScript 快速基础学习

作者: 加盐白咖啡 | 来源:发表于2020-04-02 23:38 被阅读0次

    AppleScript的必须掌握的命令:

    • tell someone do something

    AppleScript的语法十分接近自然语言,想要操作一个对象执行某些操作,只需要使用"tell命令 +对象类型 + 对象名",在之后执行end tell,结束当前的回话

    激活终端

    tell application "Terminal"
        activate -- 告诉 终端,执行激活命令
    end tell
    

    关闭终端

    tell application "Terminal"
        quit -- 告诉 终端,执行退出命令
    end tell
    

    System Events是系统应用,我们有时寄期望于在系统应用中找到某个正在执行的进程(Process)

    tell application "System Events"
        tell process "Terminal"
        end tell
    end tell
    

    在执行这段代码后,你会发现,其实什么都没有执行,不用慌,这是因为你并没有告诉"终端"要做些什么,那么我们通过entire contents命令获取Terminal内的所有UI元素

    #执行下面代码前,先激活"终端"
    tell application "System Events"
        tell process "Terminal"
            entire contents --获取区域内所有的UI元素
        end tell
    end tell
    

    执行后,会得到"终端"内的所有UI元素的完整描述

    image.png

    选择日志中的一条进行分析

    button 1 of window "终端 — -zsh — 80×24" of application process "Terminal" of application "System Events"

    其实这其中的从属关系已经十分明确了,翻译过来就是

    应用"System Events"的应用进程"Terminal"的"窗口"的"按钮1"

    • 模拟点击

    button 1的描述,我们已经很清楚了,那button 1到底对应"终端"中的哪个按钮呢?其实单从名字上看,很难看出button 1对应的是哪个按钮,那么我们用一个很简单的方法,确定它的位置,让button 1执行点击操作,通过它的点击效果反推它的位置!

    #执行下面代码前,先激活"终端"
    tell application "System Events"
        tell process "Terminal"
            (*
                注意:由于环境的差异性,直接复制这段代码到你的脚本编辑器,可能得不到想要的效果
                这里一定要输入你上面entire contents后,打印的"button 1"的完整结果
                *)
            click button 1 of window "终端 — -zsh — 80×24" of application process "Terminal" of application "System Events" 
        end tell
    end tell
    

    执行上述操作后,发现"终端"被关闭了,原来button 1对应的就是"终端"左上角的关闭按钮

    请注意:并不是所有的button 1对应的都是应用的关闭按钮,还要具体情况具体分析

    <meta charset="utf-8">

    • 模拟输入

    我们打开了终端,想看当前目录下存有哪些文件,该如何操作呢?
    想一下这个问题,我们都知道在终端中查看目录下文件的命令是ls,那么就可以将这个问题拆分为键入'ls'和点击回车两个步骤
    在AppleScript中,输入字符串的命令是keystroke,你也可以用key code实现单键点击
    我们完善一下代码:

    tell application "Terminal"
        activate
    end tell
    
    tell application "System Events"
        tell process "Terminal"
            keystroke "ls"
            delay 1 -- 延时一秒后执行
            key code 36 -- 回车的键位码为36
        end tell
    end tell
    

    完整的键位码传送门☞键位码

    我们有时需要通过组合按键的方式执行某一操作,通过在键入命令后添加using {按键A down, 按键B down}的方式,如:

    #强制关闭应用快捷键
    key code 53 using {command down, option down} -- Esc的键位码为53
    
    • 执行shell命令

    在终端中通过执行shell命令的方式可以达到和模拟键入的同样的效果

    tell application "Terminal"
        activate
        do script "ls" 
    end tell
    

    当然也可打开某路径下的文件,这里我们尝试打开"系统偏好设置"中的"键盘偏好设置"

    tell application "Terminal"
        activate
        #打开键盘偏好设置
        do script "open .  '/System/Library/PreferencePanes/Keyboard.prefPane'"
    end tell
    

    我们简单回顾一下,现在我们已经了解了:

    • 如何激活应用,并在当前的系统进程中找到它

    • 如何获取某一区域内的全部UI控件,并尝试点击其中的某一个单独控件

    • 如何实现模拟字符串输入、单键输入和组合输入

    • 如何关闭应用

    此外,我们再多了解两个帮助我们编写代码的两个小知识点:

    1.注释

    AppleScript中的注释分为单行注释和多行注释
    单行注释:#、--
    多行注释 (* 中间的部分都是注释 *)
    (上文中三种注释均有用到)

    2.输出日志

    log命令,可以通过打印辅助信息,来帮助我们编写代码
    至此,你已经掌握了实现恢复系统默认修饰键的全部基础概念,小伙伴们完全可以自己尝试写下代码
    核心代码:

    #激活
    tell application "Terminal"
        activate
        #打开键盘偏好设置
        do script "open .  '/System/Library/PreferencePanes/Keyboard.prefPane'"
    end tell
    
    tell application "System Events"
        tell process "系统偏好设置"
            #点击修饰键      
            click button "修饰键…" of tab group 1 of window "键盘" -- of application process "System Preferences" of application "System Events"
            
            #更改为默认状态
            click button "修饰键…" of tab group 1 of window "键盘" -- of application process "System Preferences" of application "System Events"
            click button "恢复成默认" of sheet 1 of window "键盘" -- of application process "System Preferences" of application "System Events"
                
            click button "好" of sheet 1 of window "键盘" -- of application process "System Preferences" of ®application "System Events"
            
        end tell
    end tell
    

    AppleScript基础知识

    1.基本模块

    语法

    #符号'¬'(option+'L') 用来将语句延续到第二行
    display dialog "This is just a test." buttons {"Great", "OK"} ¬
    default button "OK" giving up after 3 --result:调出弹窗,默认键是OK,3秒后消失
    

    变量和属性

    #变量赋值
    set myName to "John"
    copy 22 to myAge
    
    #局部变量
    local windowCount
    local agentName,agentNumber,agentHireDate
    
    #全局变量
    global gAgentCount
    global gStatementDate,gNextAgentNumber
    
    #属性
    property defaultClientName : "Mary Smith"
    
    #字符串中引用变量
    set aPerson to "GCS"
    display dialog "Hello " & aPerson & "!"
    

    类型转换

    set myText to 2 as text
    

    运算符

    3 * 7 - "1" --result 20
    

    List(数组)

    #初始化数组
    set myList to {1, "what", 3} --result: {1, "what", 3}
    set beginning of myList to 0 --首位设置为0
    set end of myList to "four" --末位设置为"four"
    set item 2 of myList to 4 --第二位设置为4
    myList --result: {0, 4, "what", 3, "four"}
    

    Record(键值对)

    #存值
    set myFullName to {firstName:"John", lastName:"Chapman"}
    #取值
    set myLastName to lastName of myFullName --result "Chapman"
    

    2.控制语句

    considering/ignoring

    "Hello Bob" = "HelloBob" --result: false
    ignoring white space --忽略空格
        "Hello Bob" = "HelloBob" --result: true
    end ignoring
    
    "BOB" = "bob" --result: true
    considering case --考虑大小写
        "BOB" = "bob" --result: false
    end considering
    

    try-error

    try
        word 5 of "one two three"
    on error
        error "There are not enough words."
    end try
    

    if

    set currentTemp to 10
    if currentTemp < 60 then
        set response to "It's a little chilly today."
    else if currentTemp > 80 then
        set response to "It's getting hotter today."
    else
        set response to "It's a nice day today."
    end if
    display dialog response
    

    repeat-exit

    set num to 0
    repeat
        -- perform operations
        if num < 5 then
            set num to num + 1
        else
            display dialog num
            exit repeat
        end if
    end repeat
    

    repeat (number) times

    set x to 3
    set power to 3
    
    set returnVal to x
    repeat power - 1 times
        set returnVal to returnVal * x
    end repeat
    return returnVal
    

    repeat while(当型循环)

    set userNotDone to true
    repeat while userNotDone
        set userNotDone to enterDataRecord()
    end repeat
    
    on enterDataRecord()
        delay 3
        false
    end enterDataRecord
    

    repeat with loopVariable (数值循环)

    set n to 3
    set returnVal to 0
    repeat with i from 0 to n
        set returnVal to returnVal + I
    end repeat
    return returnVal
    

    (数组遍历)

    set peopleList to {"Chris", "David", "Sal", "Ben"}
    #方法一
    repeat with aPerson in peopleList
        display dialog "Hello " & aPerson & "!"
    end repeat
    
    #方法二
    repeat with i from 1 to (number of items in peopleList)
        display dialog "Hello " & item i of peopleList & "!"
    end repeat
    

    String to List

    set wordList to words in "Where is the hammer?"
    repeat with currentWord in wordList
        log currentWord
        if (contents of currentWord) is equal to "hammer" then
            display dialog "I found the hammer!"
        end if
    end repeat
    

    record遍历

    #在文档中没有找到遍历record的方法,不知道是不是不小心遗漏了
    #但是在Stack Overflow中看有如下方法,引入了OC中的Foundation库,实现了record的遍历
    use framework "Foundation"
    set testRecord to {a:"aaa", b:"bbb", c:"ccc"}
    
    set objCDictionary to current application's NSDictionary's dictionaryWithDictionary:testRecord
    set allKeys to objCDictionary's allKeys()
    
    repeat with theKey in allKeys
        log theKey as text
        log (objCDictionary's valueForKey:theKey) as text
    end repeat
    

    3.函数构造

    on greetClient(nameOfClient)
        display dialog ("Hello " & nameOfClient & "!")
    end greetClient
    
    greetClient("HelloWorld")
    

    4.脚本对象

    • 定义/执行脚本
    script John
        property HowManyTimes : 0
        
        to sayHello to someone
            set HowManyTimes to HowManyTimes + 1
            return "Hello " & someone
        end sayHello
        
    end script
    
    tell John to sayHello to "Herb"
    #John's sayHello to "Jake" --result: "Hello Jake"
    #sayHello of John to "Jake" --result: "Hello Jake"
    
    • 初始化脚本
    on makePoint(x, y)
        script thePoint
            property xCoordinate:x
            property yCoordinate:y
        end script
        return thePoint
    end makePoint
     
    set myPoint to makePoint(10,20)
    get xCoordinate of myPoint  --result: 10
    get yCoordinate of myPoint  --result: 20
    
    • 继承
    script Alex
        on sayHello()
            return "Hello, " & getName()
        end sayHello
        on getName()
            return "Alex"
        end getName
    end script
     
    script AlexJunior
        property parent : Alex
        on getName()
            return "Alex Jr"
        end getName
    end script
     
    -- Sample calls to handlers in the script objects:
    tell Alex to sayHello() --result: "Hello, Alex"
    tell AlexJunior to sayHello() --result: "Hello, Alex Jr."
     
    tell Alex to getName() --result: "Alex"
    tell AlexJunior to getName() --result: "Alex Jr"
    

    写在结尾

    本文记录的只是AppleScript中的一小部分内容,笔者在网上暂时还没有找到十分详细的中文文档和介绍,所以想要更加深入的了解和学习AppleScript还是查看官方文档!

    一手资料☞AppleScript Language Guide

    参考资料:
    手把手教你用 AppleScript 模拟鼠标键盘操作,实现 macOS 系统的自动化操作

    AppleScript中的保留字


    image.png

    相关文章

      网友评论

          本文标题:AppleScript 快速基础学习

          本文链接:https://www.haomeiwen.com/subject/ewdxphtx.html