关闭包含静态文本的对话框

时间:2018-01-31 09:34:54

标签: applescript

我正在尝试编写一个脚本,该脚本应该在每个包含特定静态文本的对话框上按下OK按钮:

tell application "System Events"
    set theProcesses to application processes
    repeat with theProcess from 1 to count theProcesses
        tell process theProcess
            repeat with x from 1 to count windows
                set texts to static text of window x
                    repeat with t from 1 to (count texts)
                        if (static text t of window x whose value is "Particular text") then
                            click first button whose value is "OK" of window x
                        end if
                    end repeat
                end repeat
            end tell
    end repeat
end tell

此脚本未执行。 if语句出了点问题。

2 个答案:

答案 0 :(得分:2)

你必须检查

if (value of static text t of window x is "Particular text")

如果“确定”按钮不存在,则需要try块来忽略错误。

tell application "System Events"
    set theProcesses to application processes
    repeat with theProcess from 1 to count theProcesses
        tell process theProcess
            repeat with x from 1 to count windows
                set texts to static text of window x
                repeat with t from 1 to (count texts)
                    if (value of static text t of window x is "Particular text") then
                        try
                            click (first button of window x whose value is "OK")
                        end try
                    end if
                end repeat
            end repeat
        end tell
    end repeat
end tell

答案 1 :(得分:1)

作为一种替代方法,从理论上说,如果你有大量的进程,窗口和文本对象循环 - 可能会更快地抓住所有东西。这可以在一个单行中完成,但将其分解为单独的行不会牺牲任何速度,并提供更容易阅读的代码块:

    tell application "System Events"
        set P to a reference to every process
        set W to a reference to every window of P
        set S to a reference to (static texts of W whose value is "Particular text")
        set C to a reference to value of attribute "AXParent" of S
        set B to a reference to (buttons of C whose name is "OK")

        repeat with _b in B
            click _b
        end repeat
    end tell

用一些粗略的解释来打破它:

P包含对每个流程的引用。因为它是每个进程的引用,而不仅仅是进程本身,AppleScript不需要花费任何精力来确定这些进程到底是什么。它基本上存储了稍后在变量P中执行此操作的指令。

W是对每个流程的每个窗口的引用。到目前为止,这两行相当于前两个repeat循环,但到目前为止尚未执行任何计算,而您的脚本将经历(count windows×count processes次计算)。

S是对符合所需值的所有静态文本的引用。对于所有意图和目的,这“绕过”单独循环它们的需要,并立即抓取正确的(实际上,仍然执行循环 ,但它在更深的代码级别执行,它比AppleScript执行的任何循环花费的时间少一些。

C包含静态文本的父级,即包含所述文本的窗口。 (C代表容器 =

B最终是包含特定静态文本的每个窗口的所有“OK”按钮的集合。它是对它们的引用,所以,再次,可以一次性抓住它们,避免repeat循环。

最后,要点击B中的按钮,我们会进行第一次实际计算,然后循环遍历B。但是,B仅包含需要单击的按钮,因此不会浪费迭代,因此不需要try...end try块。

由于B中的每个按钮都是通过变量_b访问的,因此这是AppleScript将所有这些引用放在一起的地方,并执行检索按钮所需的必要(并且只是必要的)计算,这可以等同于每个repeat循环的一次迭代。

虽然这已经是获取您需要点击的按钮的一种非常有效的方法,但我们可以过滤流程和窗口以进一步改进它:

    tell application "System Events"
        set P to a reference to (processes whose background only is false)
        set W to a reference to (windows of P whose subrole is not "AXUnknown" and role is "AXWindow")
        set S to a reference to (static texts of W whose value is "Particular text")
        set C to a reference to value of attribute "AXParent" of S
        set B to a reference to (buttons of C whose name is "OK")

        repeat with _b in B
            click _b
        end repeat
    end tell

正如我所提到的,另外一个优点是,这需要更少 - 如果有任何错误处理(运行早于MacOS 10.12的OS X版本的系统可能需要将repeat循环包装在{{{} 1}}阻止;在MacOS 10.12及更高版本中,这不是必需的)。如果try返回空结果,则会在脚本中需要try块,这会导致first button of window x whose value is "OK"抛出错误。在此处,click仅包含名为“确定”的按钮(如果需要,可将B更改为name),因此value始终可以点击。

然而,为了提高稳健性并满足早期系统的需要,在错误处理方面要考虑周到是好的做法:

click

因此,值得一提的是,您的脚本可能需要额外的错误处理,而不仅仅是单个 try repeat with _b in B click _b end repeat end try 块:单击“OK”按钮后,我的猜测是对话框消失了。发生这种情况时,它包含的所有静态文本对象都会随之消失,这意味着不完整的try循环将抛出另一个错误。

感谢@user3439894测试OS X 10.8.6中的代码。