在使用应用程序块时,Automator服务脚本在检测打开的应用程序时失败

时间:2015-11-15 17:39:41

标签: macos applescript automator osx-services

我写了一个小服务脚本,在Finder上的任意文件夹上打开iTerm终端窗口。

我希望它检查iTerm是否正在运行,以及是否要在新标签中打开终端会话而不是现有标签。

脚本是这样的:

on run {input, parameters}

set cdPath to "cd " & (quoted form of POSIX path of (input as string))

if application "iTerm" is running then
    display notification "running"
    tell application "iTerm"
        set termWin to (current terminal)
        tell termWin
            launch session "Default"
            tell the last session
                write text cdPath
            end tell
        end tell
    end tell
else
    display notification "not running"
    tell application "iTerm"
        activate
        set termWin2 to (current terminal)
        tell termWin2
            tell the last session
                write text cdPath
            end tell
        end tell
    end tell
end if
return input
end run

问题是,当我将脚本作为服务运行时,它总是表现得好像iTerm已经在运行(显示“运行”通知),即使iTerm已经关闭且非常明显没有运行。

但是,如果我将相同的脚本粘贴到脚本编辑器(将cdPath设置为文字,如set cdPath to "cd /etc")并直接执行它,它将正常工作,打开一个新的iTerm实例或重用现有的实例并创建一个新选项卡,并显示相应的通知。

如果我将脚本简化为仅显示通知(如下所示删除tell aplication块:

on run {input, parameters}

set cdPath to "cd " & (quoted form of POSIX path of (input as string))

  if application "iTerm" is running then
    display notification "running and path is " & cd
  else
    display notification "not running and path is " & cdPath
  end if
  return input
end run

它会按预期运行(相应地显示“正在运行”或“未运行”。)

但是,如果我添加“告诉应用程序”部分,它将始终通过“运行”分支,无论如何。

例如:

on run {input, parameters}
set cdPath to "cd " & (quoted form of POSIX path of (input as string))

  if application "iTerm" is running then
    display notification "running"
  else
    display notification "not running"
    tell application "iTerm"
        activate
    end tell
  end if
  return input
end run

将始终打开iTerm(即使tell application "iTerm"在“未运行”分支上,但显示“正在运行”分支中的“正在运行”通知...仅仅存在“告诉”应用程序“将触发打开应用程序,然后运行服务。

有没有办法规避这个?为什么“tell application”块会打开app,即使它位于条件的另一个分支上?

2 个答案:

答案 0 :(得分:1)

使用"正在运行"正在导致一个tell块的运行。使用系统事件获取正在运行的进程的名称,以检查应用程序是否正在运行。以下是您最终脚本示例的重写,可以按照您的意愿使用。

on run {input, parameters}

    set cdPath to "cd " & (quoted form of POSIX path of (input as string))

    tell application "System Events" to set theProcesses to name of every process whose visible is true

    if theProcesses contains "iTerm" then
        display notification "running"
    else
        display notification "not running"
        tell application "iTerm"
            activate
        end tell
    end if
    return input
end run

如果你仍然无法使用它(在运行OS X 10.11.1的机器上运行,那么你也可以在运行脚本中包含任何tell块的地方添加技巧,所以它永远不会编译到运行时。这是原始脚本,证明了这一点:

on run {input, parameters}

    set cdPath to "cd " & (quoted form of POSIX path of (input as string))

    tell application "System Events" to set theProcesses to name of every process

    if theProcesses contains "iTerm" then
        display notification "running"

        run script "tell application \"iTerm\"
        set termWin to (current terminal)
        tell termWin
            launch session \"Default\"
            tell the last session
                write text cdPath
            end tell
        end tell
    end tell"
    else
        display notification "not running"
        run script "tell application \"iTerm\"
        activate
        set termWin2 to (current terminal)
        tell termWin2
            tell the last session
                write text cdPath
            end tell
        end tell
    end tell"
    end if
    return input
end run

答案 1 :(得分:0)

我想我找到了一个解释:

  • 任何“正在运行”-phrase需要在它前面有一个短暂的“延迟”才能可靠地返回一个真正的答案......但如果被称为应用程序,将不会这样做服务 - ?因为?
  • 此外,我猜Automator脚本在作为服务运行之前以某种方式“预处理” 评估(播放)所有if-branches,从而激活“以防万一”。
    在jweaks代码中,iTerm仅在第2个子句中直接受到影响(“告诉......”)。

在ScriptEditor,Automator和Safari中的服务中尝试此代码:

display notification "" & running of application "TextEdit"
tell application "TextEdit" to activate
quit application "TextEdit"
display notification "" & running of application "TextEdit"

您将从AppleScript / Automator(=> false + true )和Safari(true + true)获得不同的结果。
尤其是来自第二次通知的AppleScript / Automator的 true 非常有说服力
...但是,如果你在“退出”行之后插入一分钟延迟,比如0.01,则运行将被测试为“假” - 如果脚本是从AppleScript / Automator中运行的。