【问题标题】:Applescript and Automator - Safari gets stuck and I have to push Esc to continueApplescript 和 Automator - Safari 卡住了,我必须按 Esc 才能继续
【发布时间】:2018-11-25 05:22:13
【问题描述】:

这个简单的 Applescript 按预期工作:

tell application "Safari"
    activate
    set theURL to URL of front document
end tell

我现在尝试对其进行 Automator 操作/服务:

on run {input, parameters}
    tell application "System Events"
        if (name of the first process whose frontmost is "true") is "Safari" then
            set theURL to URL of front document
        end if
    end tell
    return theURL
end run

但这会返回错误消息:

“运行 AppleScript”操作遇到错误:“系统事件出错:无法获取文档 1 的 URL。”

嗯,所以我在 Automator 中添加了一个 tell application "Safari" to activate,以确保收到这些命令的是 Safari:

on run {input, parameters}
    tell application "System Events"
        if (name of the first process whose frontmost is "true") is "Safari" then
            tell application "Safari"
                activate
                set theURL to URL of front document
            end tell
        end if
    end tell
    return theURL
end run

很奇怪,现在 Automator 动作卡在 0 % 上(如菜单栏中的 Automator 齿轮所示)。要完成脚本,我必须推送Esc

事实上,如果我在 0 % 卡住时退出 Safari,当我尝试切换回 Safari 直到我按 Esc 时,它会保持后台运行。按下 Esc 后,Safari 自动进入前台,Automator 操作完成。

即:

  1. 在 Safari 中选择一些文本,然后从上下文菜单中选择此服务。
  2. 服务卡在 0 %。
  3. 切换到另一个应用程序 A。这按预期工作。服务仍停留在 0 %。
  4. 尝试使用 cmd-tab、dock 或其他方式切换回 Safari。没有任何反应,A 仍在前台,服务卡在 0 %。
  5. 按 Esc。现在服务结束,Safari 进入前台。

最后,我设置了 Automator 操作来替换

那么,为什么我不能访问第一个版本的 URL?为什么它会卡在第二个版本中?我应该如何写这个来完成我想要的?

编辑:澄清我想要实现的目标。我想从 Safari 最前面的窗口获取 URL,处理 URL,然后在其他地方使用它。我已删除 Automator 工作流程中的处理和“其他地方”部分以简化问题。

【问题讨论】:

  • 阅读完 cmets,您的预期用户流程是否类似于:1. 用户使用 SafariChrome,然后他们选择例如Safari > Services > <NameOfService> 从菜单栏中。 2. 您的脚本检索 URL 并将其分配给 theURL 变量。 3. 您的脚本还会确定 URL 来自哪个浏览器(SafariChrome),以便您可以执行不同的逻辑? 4. 但是,如果用户正在使用另一个应用程序(不是 SafariChrome)并选择 Safari > Services > <NameOfService>从菜单栏,那么你的脚本应该什么都不做?
  • @RobC 是的,目的是在其他地方插入部分 URL。但是,Chrome 和 Safari 的 AS 词典略有不同。

标签: safari applescript automator


【解决方案1】:

发生错误是因为您在无法工作的System Events 告诉块中运行 Safari 术语。

其实没必要把 Safari 放在最前面。这条线应该可以完成这项工作。

on run {input, parameters}
    tell application "Safari" to return URL of front document
end run

更健壮的版本检查前端文档是否存在

on run {input, parameters}
    tell application "Safari"
        if exists document 1 then return URL of front document
        return missing value
    end tell
end run

如果您要设置 Automator 服务,请将 Service receives 设置为 无输入

【讨论】:

  • 当我使用你的第一个版本时它仍然卡住。这是整个 Automator 操作的屏幕截图:imgur.com/a/92zdIbb。另外,如何将您的一个衬里的返回值插入到变量中?谢谢:-)
  • 那个奇怪的系统事件块的目的是什么,我猜它是瓶颈? Safari 不需要位于最前面。 AppleScript 操作返回 URL 以将其传递给下一个操作。
  • 我将从 Chrome 和 Safari 运行此服务,并且需要知道它是从哪个程序运行的。如果我添加日志记录,则告诉系统事件块按预期完成,并且我进入以下 if 子句没有问题。
  • 每个(可编写脚本的)应用程序都有一个frontmost 属性。您可以简单地检查if frontmost of application "Safari" then ...
  • imgur.com/a/ePt2CC9 - 它仍然卡住了。你知道如何将 Safari 返回的 URL 存储在变量中吗?
【解决方案2】:

您可以执行以下操作来确定 URL 以及该 URL 来自哪个应用程序/浏览器。

为了便于理解,以下要点中的代码故意冗长,此外我不确切知道您想要实现什么。然而,它的作用是为您提供实现您想要做的事情的一般要点。

它执行以下操作:

  1. 获取最前面的应用程序的名称。
  2. 当最前面的应用程序是 SafariGoogle Chrome 时,它将首先检查一个窗口是否可用。
    • 如果窗口不可用,它将通知用户。
    • 如果一个窗口可用,它将显示一个对话框,指示 URL 和它来自的浏览器的名称。这只是为了证明变量 theURLwhichBrowser 包含您需要的信息。
  3. 如果服务不是SafariGoogle Chrome 运行,它将通知用户它必须从任一 运行>SafariGoogle Chrome

on run {input, parameters}

  tell application "System Events" to set theActiveApp to name of first process where it is frontmost

  set theURL to "unknown"
  set whichBrowser to "unknown"

  if theActiveApp is equal to "Safari" then
    tell application "Safari"
      if exists document 1 then
        set theURL to URL of current tab of window 1
        set whichBrowser to theActiveApp
      else
        display dialog "This service requires active window in Safari with a URL" & return & return & "Try opening a new window." with icon caution
        return
      end if
    end tell
  else if theActiveApp is equal to "Google Chrome" then
    tell application "Google Chrome"
      if exists window 1 then
        set theURL to URL of active tab of window 1
        set whichBrowser to theActiveApp
      else
        display dialog "This service requires active window in Chrome with a URL" & return & return & "Try opening a new window." with icon caution
        return
      end if
    end tell
  end if

  -- The Service was NOT run from either Safari or Google Chrome
  if theURL = "unknown" and whichBrowser = "unknown" then
    tell application "Finder"
      activate
      display dialog "This Service must be run from either Safari or Google Chrome" & theActiveApp with icon caution
    end tell
  else
    -- Report the results
    display dialog "The url is: " & theURL & return & return & "From app: " & theActiveApp
  end if

  -- ONLY return theURL to the next task if we've got it.
  if theURL ≠ "unknown" then
      return theURL
  end if

end run

注意

在最后一段写着:

if theURL ≠ "unknown" then
    return theURL
end if

如果 theURL 未知(即服务未从 Safari/Chrome 运行或未在浏览器中打开窗口),这将导致工作流停止运行。否则它会将theURL 传递给下一个Automator 任务。


只有必要对话框的脚本版本

以下版本将仅显示必要的对话框,不会在对话框中报告 theURLwhichBrowser 变量。

on run {input, parameters}

  tell application "System Events" to set theActiveApp to name of first process where it is frontmost

  set theURL to missing value

  if theActiveApp is equal to "Safari" then
    tell application "Safari"
      if exists document 1 then
        set theURL to URL of current tab of window 1
      else
        display dialog "This service requires active window in Safari with a URL" & return & return & "Try opening a new window." with icon caution
        return -- return early
      end if
    end tell
  else if theActiveApp is equal to "Google Chrome" then
    tell application "Google Chrome"
      if exists window 1 then
        set theURL to URL of active tab of window 1
      else
        display dialog "This service requires active window in Chrome with a URL" & return & return & "Try opening a new window." with icon caution
        return -- return early
      end if
    end tell
  end if

  if theURL is equal to missing value then
    -- The Service was NOT run from either Safari or Google Chrome
    tell application "Finder"
      activate
      display dialog "This Service must be run from either Safari or Google Chrome" & theActiveApp with icon caution
    end tell
  else
    -- ONLY return theURL to the next Automator task if we've got it.
    return theURL
  end if

end run

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多