【问题标题】:Automator service script fails at detecting open app when tell application block is used使用告诉应用程序块时,Automator 服务脚本无法检测到打开的应用程序
【发布时间】:2015-11-15 17:39:40
【问题描述】:

我编写了一个小服务脚本来在 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" 它位于“未运行”分支上,但会显示来自“正在运行”分支的“正在运行”通知......仅存在“告诉应用程序”将触发打开应用程序然后运行服务。

有没有办法避免这种情况?为什么“告诉应用程序”块会打开应用程序,即使它在条件的另一个分支上?

【问题讨论】:

  • 什么|输入|正在传递给脚本?是文件路径的字符串吗?
  • 当作为服务运行时,它会收到一个路径。但我认为它与输入无关,而是与“告诉应用程序”块有关。当我删除它们时,它可以工作(尽管它没用),并且我让它在我的第二个代码块中工作(正确处理输入)。

标签: macos applescript automator osx-services


【解决方案1】:

“正在运行”的使用导致了告诉块的运行。使用系统事件获取正在运行的进程的名称以检查应用程序是否正在运行。这是对最终脚本示例的重写,可按您的意愿工作。

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 的机器上确实如此,那么你也可以添加将任何告诉块包装在运行脚本中的技巧,所以它永远不会编译,直到运行时。这是您的原始脚本,展示了这一点:

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

【讨论】:

  • 不,抱歉。它与我的版本具有相同的效果。在此处查看实际情况:vid.me/Wmic
  • 即使 iTerm 没有真正运行,它也会显示“正在运行”。在这里找到了一条线索stackoverflow.com/a/16071855/1426539,上面写着“在tell应用程序上编译的行为将使应用程序启动。”,但不知道如何解决这个问题...... :(
  • 这是我的脚本绝对有效。 (dl.dropboxusercontent.com/u/3462254/ServiceWorking.mov)我无法阅读视频中的代码(质量差),所以无法测试。请注意,我正在使用 TextEdit 对其进行测试,因为我没有 iTerm。您也应该使用 TextEdit 进行测试,以确保 iTerm 不是问题。
  • 这里:dropbox.com/s/xz2kl7jhcuwhyat/Automator_Failing_2.mov?dl=0 原始代码正是您发布的内容。这里我对其进行了修改,使失败更加明显(Service首先打开关闭的iTerm,并立即要求退出)
  • 这不准确,因为您正在运行基于 Finder 选择的服务(这就是为什么我之前询问激活了哪些选择服务)。如果您使用 TextEdit 发短信,您会得到相同的行为吗?
【解决方案2】:

我想我找到了解释:

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

在 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 中运行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-05
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多