当前位置: 首页 > 知识库问答 >
问题:

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

黎曾笑
2023-03-14

考虑下面的Apple脚本:

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没有运行,它就会启动,脚本报告“正在运行”。这不是我想要或期望的行为。请注意,当在苹果脚本编辑器中运行时,它按照期望/预期的方式工作。

这是一个已知的问题吗?还是出于某种原因而故意这样做?有人能让它按预期工作吗?(顺便说一句,我正在运行OSX 10.7.5;我不知道如何让osascript报告版本号)。

如果您注释掉let/end tell行,它的行为就像我所期望的那样:如果Safari没有运行,它就不会启动它,并打印“未运行”。所以在我看来,tell是导致Safari被启动的原因,但它不需要实际执行,只需出现在脚本中...?有一段时间,我想知道这是否就是tell应该工作的方式,但是由于它在AppleScript编辑器中不这样工作,我想不会...

事实上,这里有另一个类似行为的版本,madder:

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,即使在返回语句之后,tellif false块中!(但是,这在AppleScript编辑器中是很好的。)

顺便说一句,这种行为不限于Safari,但也不是普遍的:

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

那么,有人知道我该如何解决这个问题吗?这是一个osascriptbug吗?还是我遗漏了AppleScript的语义?

对于上下文:我试图写一个脚本(嵌入/从某个python调用),它查询打开的浏览器打开的任何选项卡的网址;除了它总是启动Safari,不管它是否打开,我都做得很好。我已经把这种不受欢迎的行为归结为上面所示的简单测试用例。我不知道有什么方法可以在不使用osascript的情况下从python运行这个脚本,除了appcript,我不想使用它,因为它不再被开发/支持/推荐。

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

共有3个答案

蒋弘致
2023-03-14

好吧,我知道这个问题真的很老,但是我偶然发现了一个不同的问题,不得不考虑其中一些回答有多复杂。

实现你想要的(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!

公孙茂学
2023-03-14

一些信息:

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

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

那就是“增强型应用程序对象模型”。如果一个应用程序仍然启动(例如,您第一次编译

况博容
2023-03-14

我怀疑您之所以会看到这种情况,是因为每次使用osascript从命令行调用脚本时,脚本都在编译中。

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

使用预编译文件(即scpt)中的osascript从命令行调用脚本不会导致这种行为,因为不需要进行编译。

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

如果你不想使用。如果你想使用一个纯文本文件,那么你可以尝试在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

 类似资料:
  • 有人能想出一个变通方法来解决osascript索引按名称瓶颈引用同一应用程序的多个实例吗? 如果我们获得两个进程id-一个用于同一个应用程序的两个不同实例,osascript返回相同的实例来交换其中一个pid-就像它首先将pid映射到一个应用程序名称,然后检索具有该名称的第一个应用程序进程一样。 例如,启动两个不同的VLC实例。应用程序,播放两个不同的视频文件,类似: 然后获取两个单独的应用程序进

  • 我有一个spring启动应用程序,我需要通过进入文件夹目录并通过命令行启动我的web应用程序来启动它。我有一门课叫应用。java及其内部代码如下所示。 我设置了类路径,然后试图运行命令"",但我得到了这个错误消息""

  • 问题内容: 我是Flask的新手,我想确保Redis服务器正在运行,如果没有运行,请启动它。这是我所拥有的: 但是,我收到一个错误“ OSError:[Errno 2]没有这样的文件或目录” 有没有更简单的方法来检查Redis服务器是否正在运行? 问题答案: 使用 ping cmd的redis: 样本输出:

  • 显示 “无法导入资源”@AcmeDemoBundle/Controller/SecuredController。php“from”D:/UserData/WWWRoot/Symfony/app/config/routing。yml”。确保“AcmeDemoBundle/Controller/SECUEDCONTROLLER”。php“bundle已正确注册并加载到应用程序内核类中。” 这是我的 处

  • 我正在使用CuratorFramework(我还是个新手)来连接Zookeeper实例。我想导入配置,但在此之前,我想测试我的程序是否能够连接到Zookeeper。到目前为止,我有这样的想法: 我已经在本地机器上启动了ZooKeeper,我检查了与zkCli的连接,客户端可以连接到它。zookeeperCon变量设置为“127.0.0.1:2181”(我也尝试了localhost:2181)。问题

  • 问题内容: 我是一名Android开发人员,我想在我的应用程序中编写一条语句。在此语句中,我要检查默认浏览器(Android OS中 问题答案: 添加下面的Helper类: 现在,你可以从以下代码中检查所需的应用程序是否正在运行: