如何检查的AppleScript如果一个应用程序正在运行,而无需启动它 - 通过osascript工

2019-08-31 09:28发布

考虑下面的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

问题:当我通过运行这个osascript命令行实用程序,如果Safari浏览器没有运行,它就会启动,该脚本报告“运行”。 这不是我的愿望或期望的行为。 需要注意的是它的工作原理为所需/预期时的AppleScript编辑器中运行。

这是一个osascript错误/已知的问题? 或者是它在某种程度上预期的原因,我很想念行为? 任何人都可以得到所期望它的工作? (顺便说一句我运行OSX 10.7.5,我不能看到如何让osascript报告版本号)。

如果您注释掉tell / end tell线条,它的行为,我期望:如果Safari浏览器没有运行,它不启动它,并打印“未运行”。 所以,在我看来 ,像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

这仍然总是启动Safari浏览器,即使tell是内部if false块return语句后! (但同样,这是的AppleScript编辑器的罚款。)

顺便说一句,这种行为并不局限于Safari浏览器,但它也并不普遍:

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

因此,没有任何人有,我怎么可能解决这个修复或路由任何想法? 它是一个osascript错误吗? 还是我失去了一些东西有关AppleScript的语义?

对于背景:我试图写一个脚本(被嵌入/从一些Python调用),其查询任何标签的网址,打开的浏览器他们有开放的; 我知道了,不过它总是启动Safari浏览器,无论是打开还是不是所有工作的罚款。 我归结是不良行为,以上面所示的简单的测试案例。 我不知道的任何方式,而不使用运行蟒蛇这个脚本osascript ,比其他appscript ,我不想使用,因为它不再开发/支持/建议 。

非常感谢所有输入/见解!

Answer 1:

我怀疑你正在这样做的原因是因为每次你从osascript脚本正在编译的命令行调用脚本。

编译在告诉应用程序将AFAIK使应用程序启动的行为。

调用从预编译的文件即与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

运行脚本 ,脚本需要时才编译。 你需要像逃避任何引号字符在我的例子。

如果你写一个正常的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

该脚本可以从与osascript命令行运行

例:

osascript /Users/USERNAME/Desktop/foo.scpt

请注意,该脚本保存为一个脚本编译。 这将好的工作,你也可以保存和使用它作为一个纯文本脚本。

osascript /Users/USERNAME/Desktop/foo.applescript



Answer 2:

一些信息:

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

tell application "iTunes"
    if it is running then
      pause
    end if
end tell

你也可以这样做的:

if application "iTunes" is running then
    tell application "iTunes" to quit
end if

你也可以这样做:

get name of application "iTunes"
get version of application "iTunes"

并完成旅程:

get id of application "TextEdit" --> "com.apple.TextEdit"
tell application id "com.apple.TextEdit"
    make new document
end tell

这是“增强应用对象模型”。 如果一个应用程序仍会启动(例如,你第一次编译和执行脚本),我认为这是因为已经拿到从应用程序的一些信息,它并没有在字典中(或类似的东西找到...? )。



Answer 3:

好了,我知道这个问题是真的老了,但我无意中发现了它寻找一个不同的问题,并在考虑如何复杂一些这些反应都不得不管。

简单的代码来实现你想要的(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

在旧系统中, 使用的语法为:

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

其中一个一定要为你工作,AppleScript的解决方案勇敢的搜索行动,只有当一个应用程序正在运行。


哦! 特别提示:如果你不知道该应用程序的名称到底是什么(它通常但并非始终是应用程序的名称),编码最终脚本运行之前...

tell application "System Events"
   get every application process
end tell

而在结果中找到你的应用程序进程名。

下面是运行该命令的屏幕抓取。 (注意: 谷歌Chrome浏览器帮助实例的不计其数。感谢谷歌!)

HTH!



Answer 4:

tell application "Finder"
    set applicationsnames to get the name of every process whose visible is true
end tell

set appName to "Safari"

if applicationsnames does not contain appName then
    say (appName & " is not running")
    --add here what you want to happen

end if
return applicationsnames

这是返回{"Finder", "JavaAppLauncher", "firefox", "Microsoft Word", "iTunes", "AppleScript Editor"}

希望这可以帮助



Answer 5:

所有预先做出的答案,从同样的问题受到影响,但是:

他们寻找其名称的应用程序。 然而,用户可以重命名的应用程序,然后脚本会认为应用程序不运行的时候,其实它的作用。

要正确检查正在运行的应用程序,它应该由它的捆绑ID,用户可以不改变被发现。

束ID可以与该命令询问,例如:

tell application "System Events"
    get bundle identifier of application process "Safari"
end tell

要检查是否具有特定包ID的应用程序正在运行,使用以下代码:

tell application "System Events"
    set ids to bundle identifier of every application process
    if ids contains "com.apple.safari" then
        return "Running"
    else
        return "Not running"
    end if
end tell

此外,这里有一个例子来检查,如果一个应用程序正在运行,则退出它,然后重新启动它,保证同样的应用程序是重新启动那是以前运行,而不是其它副本也可能存在:

set bundleID to "com.apple.safari"
set apps to runningApps(bundleID)
set appCount to length of apps
if appCount is not 0 then
    quit application id bundleID
    repeat while length of runningApps(bundleID) = appCount
        -- wait for the app to quit
    end repeat
    open first item of apps
end if

on runningApps(bundleID)
    -- The try block is to catch the rare case of having more than one
    -- copy of an app running at the same time. Unfortunately, in that
    -- case this code will not run as expected, because we don't get the
    -- correct list of multiple items back then. But at least the script
    -- will not crash from it but handle it gracefully.
    tell application "System Events"
        try
            return application file of (every application process whose bundle identifier = bundleID)
        end try
    end tell
    return {}
end runningApps


Answer 6:

我这里所描述试图建立播放/暂停VLC或iTunes一个AppleScript(由BetterTouchTool手势触发)同样的问题,但只有iTunes的,如果VLC没有运行(由于我的工作流)和,自然,只有VLC而它的运行。 (我用的是自动暂停/播放触发的iTunes在VLC的设置,启动和退出应用程序。)

VLC总是在BTT的每一个重新开张后的第一次使用BetterTouchTool触发的推出,字典高速缓存在这一点上删除,AppleScript的处理程序有,如果讲的是针对它为了调用启动每个脚本应用它字典。

我没有找到任何东西,这可以避免任何地方; 有一些尝试,但没有为我工作由脚本处理程序字典呼叫是什么,我们可以影响。 我想出了这个肮脏的解决方法:

  • 创建仅包含包括VLC的告诉线路分离的AppleScript文件
  • 在一些地方将它保存在它不会惹恼你
  • 更换含一条线在原有的AppleScript的告诉大家,运行该脚本行

这将导致脚本不调用应用程序(VLC,在我的情况)直接,只有剧本,这意味着应用程序不需要发动的第一次编译。

VLC将需要启动一旦单独的文件被调用,但是,好了,如果你调用该文件,以告诉VLC的东西,你将有VLC已经打开(或将要打开它)反正。

该AppleScript的我通过BetterTouchTool触发(在触控板上一个特定抽头,在我的情况)调用看起来是这样的:

if application "iTunes" is running and not application "VLC" is running then
tell application "iTunes" to playpause

如果结束如果应用“VLC”正在运行,然后运行脚本“/Users/jannis/bin/PlayVLC.scpt”如果结束

单独的AppleScript文件(“PLayVLC.scpt,保存在一个名为文件夹‘在我的用户文件夹仓’,我手动创建很久以前这样的目的)就是这样的:

tell application "VLC" to play

如果您手动打开脚本,它当然会还推出VLC。 但是,希望不会是必要的时候,或曾经。

其实,我如果这造成任何更深层次的问题,我不知道,因为我不是一个职业编码器不知道; 如果是的话,请通知我。 我希望这可以帮助任何人!



文章来源: How to check in AppleScript if an app is running, without launching it - via osascript utility