如果应用程序正在运行,如何在不启动的情况下检查AppleScript - 通过osascript实用程序

gim*_*and 44 safari macos applescript osascript

请考虑以下AppleScript:

on is_running(appName)
    tell application "System Events" to (name of processes) contains appName
end is_running

set safRunning to is_running("Safari")
if safRunning then
    tell application "Safari"
      -- Stuff I only want executed if Safari is running goes here.
    end tell
    return "Running"
else
    return "Not running"
end if
Run Code Online (Sandbox Code Playgroud)

问题:当我通过osascript命令行实用程序运行时,如果Safari未运行,它将启动并且脚本报告"正在运行".这不是我想要或期望的行为.请注意,在AppleScript编辑器中运行时,它可以按预期/预期工作.

这是一个osascript错误/已知问题吗?或者是因为我失踪的原因而在某种程度上是预期的行为?任何人都可以按需要让它工作吗?(顺便说一下,我正在运行OSX 10.7.5;我看不到如何osascript报告版本号).

如果你注释掉tell/ end telllines,它的行为就像我期望的那样:如果Safari没有运行,它就不会启动它,并打印"Not running".所以在我看来,tell是什么导致Safari被启动,但它不需要实际执行,只是出现在脚本中......?有一阵子,我想知道,如果这也许只是如何tell应该工作,但由于它并不像这样的AppleScript编辑工作,我想不是...

事实上,这是另一个具有类似行为的茜草版本:

on is_running(appName)
    tell application "System Events" to (name of processes) contains appName
end is_running

set safRunning to is_running("Safari")
return safRunning
if false then
    tell application "Safari"
    end tell
end if
Run Code Online (Sandbox Code Playgroud)

这仍然总是启动Safari浏览器,即使tell是内部if false块return语句后!(但同样,这在AppleScript编辑器中也没问题.)

顺便说一句,这种行为不仅限于Safari,它也不是通用的:

  • 受影响的应用程序包括:Safari,TextEdit,iPhoto,AppleScript编辑器,iTerm,......
  • 不受影响的应用包括:谷歌浏览器,iTunes,预览,邮件,终端,地址簿,Echofon,...

那么,有没有人对我如何修复或解决这个问题有任何想法?这是一个osascript错误吗?或者我错过了AppleScript的语义?

对于上下文:我正在尝试编写一个脚本(要从某个python中嵌入/调用),该脚本查询打开的浏览器以查找它们已打开的任何选项卡的URL; 我已经完成了所有工作,除了它总是启动Safari,无论它是否开放.我已经将这种不良行为归结为上面显示的简单测试用例.我不知道的任何方式,而不使用运行蟒蛇这个脚本osascript,比其他appscript,我不想使用,因为它不再开发/支持/建议.

非常感谢所有的投入/见解!

小智 49

一些信息:

"增强的应用程序对象模型":

tell application "iTunes"
    if it is running then
      pause
    end if
end tell
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

if application "iTunes" is running then
    tell application "iTunes" to quit
end if
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

get name of application "iTunes"
get version of application "iTunes"
Run Code Online (Sandbox Code Playgroud)

并完成旅程:

get id of application "TextEdit" --> "com.apple.TextEdit"
tell application id "com.apple.TextEdit"
    make new document
end tell
Run Code Online (Sandbox Code Playgroud)

这就是"增强的应用程序对象模型".如果一个应用程序仍然启动(例如,第一次编译和执行脚本)我认为这是因为AS必须从应用程序中获取一些它没有在字典中找到的信息(或类似的东西......? ).

  • 它可能无法完全解决这个问题,但在谷歌搜索"如何检查AppleScript是否有应用程序正在运行"并找到这篇文章后,我很感谢这是已发布的答案之一! (8认同)

mar*_*nte 49

我怀疑你得到这个的原因是因为每次从osascript命令行调用脚本时,脚本都被编译.

tell应用程序上编译的行为将使应用程序启动.

使用来自预编译文件的osascript从命令行调用脚本,即.scpt不会导致此行为,因为没有编译要完成.

但是从纯文本(.txt,.sh)文件中调用它将会启动应用程序.

如果您不想使用.scpt文件并且想要使用纯文本文件,那么您可以尝试在AppleScript 中放置运行脚本命令.

on is_running(appName)
    tell application "System Events" to (name of processes) contains appName
end is_running

set safRunning to is_running("Safari")
if safRunning then
    run script "tell application \"Safari\" 

open location \"http://google.com\"

    end tell"
    return "Running"
else
    return "Not running"
end if
Run Code Online (Sandbox Code Playgroud)

运行脚本中的脚本仅在需要时编译.您将需要像我的示例中那样转义任何字符,如引号.

如果您首先在普通的AppleScript文档中编写脚本并编译它以检查错误,将会更容易.

然后将其复制到纯文本文件.


更新**

我上面使用的方法是在我回答这里之前的一段时间里用来解决这个问题的旧脚本.

答案是有效的,而不是试图优雅.;-)

我其实喜欢下面的user1804762方法.因为它确实有效但感觉答案不够清楚,所以我将举例说明如何使用它.

set appName to "Safari"

if application appName is running then

    tell application id (id of application appName)

        open location "http://google.com"
    end tell
    return "Running"
else
    return "Not running"
end if
Run Code Online (Sandbox Code Playgroud)

可以使用osascript从命令行运行此脚本

例:

osascript /Users/USERNAME/Desktop/foo.scpt

请注意,脚本将保存为已编译的脚本.这将正常工作,您也可以将其保存并用作纯文本脚本.

osascript /Users/USERNAME/Desktop/foo.applescript


das*_*ard 7

好吧,我知道这个问题真的很老了,但我偶然发现它正在寻找一个不同的问题,不得不考虑一下这些问题的复杂程度.

实现您想要的(ed)的简单代码是:

tell application "System Events"
  if application process "Safari" exists then
    -- do stuff you want to do only if Safari exists
  end if
end tell
Run Code Online (Sandbox Code Playgroud)

在较旧的系统上,语法过去是:

tell application "System Events"
  if exists of application process "Safari" is true then
    -- do stuff you want to do only if Safari exists
  end if
end tell
Run Code Online (Sandbox Code Playgroud)

其中一个绝对应该适合你,Applescript解决方案的勇敢搜索者只有在应用程序运行时才能采取行动.


哦! 额外提示:如果您不确定应用程序进程名称是什么(通常但不总是应用程序名称),那么在编写最终脚本运行之前...

tell application "System Events"
   get every application process
end tell
Run Code Online (Sandbox Code Playgroud)

并在结果中找到您的应用进程名称.

这是运行该命令的屏幕抓取.(请注意Google Chrome Helper实例的数量.感谢Google!)

在此输入图像描述

HTH!

  • 这就是我改用 Firefox 的原因 (2认同)