【问题标题】:How do I check that an application is running when I have its file path?当我有文件路径时,如何检查应用程序是否正在运行?
【发布时间】:2013-09-13 05:49:45
【问题描述】:

我正在尝试使脚本(除其他外)需要知道某个应用程序是否正在运行。为了获得最大的稳健性,我想通过它的文件路径找到它。或者,如果失败,则通过其名称或包标识符找到它,并检查其文件路径。只是为了使事情复杂化,我有 POSIX 形式的应用程序路径

我想做的是这样的(这里以TextEdit为例

tell application "System Events"
    item 1 of (processes whose application file is "/Applications/TextEdit.app")
end tell

但这不起作用...

我不是 AppleScript 天才,但我发现我至少可以从它的包标识符中找到一个正在运行的进程,然后将其文件作为无用的“别名”:

tell application "System Events"
    application file of item 1 of (processes whose bundle identifier is "com.apple.TextEdit")
end tell

我收到alias Macintosh HD:Applications:TextEdit.app:
太好了,但我无法将其与任何东西相提并论!我什至无法将 application file-alias 转换为 POSIX 路径并将它们作为字符串进行比较。我也不能将我拥有的 POSIX 路径翻译成别名,然后进行比较。

那么,我该怎么办?

更新/解决方案

向 Paul R 和 regulus6633 提供有用的提示!

我可能应该更具体一点。正如我在下面的一些 cmets 中所写的那样,当你只有它的路径时确定一个是否正在运行并不是脚本应该做的全部。重点其实是定位匹配路径的进程,然后做一些GUI脚本。 IE。我不能使用简单的ps,因为我需要访问 GUI/AppleScript 的东西(特别是进程的窗口)。

从技术上讲,我可以通过ps 来获取 PID(如下面的 regulus6633 所示),但 AppleScript 已经在另一个 shell 中运行的 Ruby 脚本生成的 shell 中运行,而且看起来很混乱。

最终这样做了(这似乎很多,但在我正在做的事情的背景下这是必要的):

on getProcessByPOSIXPath(posixPath, bundleID)
    -- This file-as-alias seems really complex, but it's an easy way to normalize the path endings (i.e. trailing slash/colon)
    set pathFile to (POSIX file posixPath) as alias
    set thePath to pathFile as text
    tell application "System Events"
        repeat with activeProcess in (processes whose bundle identifier is bundleID)
            try
                set appFile to application file of activeProcess
                if (appFile as text) is equal to thePath then return activeProcess
            end try
        end repeat
        return null
    end tell
end getProcessByPOSIXPath

请注意,posixPath 参数必须是应用程序包的路径(例如“/Applications/TextEdit.app/”,带或不带斜杠),而不是包内的实际可执行文件。
该函数将返回与给定 POSIX 路径匹配的进程(如果未找到,则返回 null)

bundleIdentifier 参数不是必需的,但它通过缩小进程列表大大加快了一切速度。如果你想让它只使用路径,你可以这样做

on getProcessByPOSIXPath(posixPath)
    set pathFile to (POSIX file posixPath) as alias
    set thePath to pathFile as text
    tell application "System Events"
        repeat with activeProcess in processes
            try
                set appFile to application file of activeProcess
                if (appFile as text) is equal to thePath then return activeProcess
            end try
        end repeat
        return null
    end tell
end getProcessByPOSIXPath

【问题讨论】:

    标签: applescript


    【解决方案1】:

    我们在 Mac 上有很多工具,您通常可以找到解决方案。在您的情况下,我同意您不能过滤“应用程序文件”。您可能只能过滤字符串、数字或布尔值。

    但是,我们确实有其他工具,例如命令行,并且我们也可以访问 Objective-c 方法。这是一个命令行方法...

    set applicationPosixPath to "/Applications/Utilities/AppleScript Editor.app"
    
    try
        do shell script "/bin/ps -ef | grep " & quoted form of applicationPosixPath & " | grep -v grep"
        return "application is running"
    on error
        return "application is not running"
    end try
    

    【讨论】:

    • 当然,我可以使用 shell 脚本摆脱它。我的第一个想法也跑到 ps+grep 上。但是由于这个脚本已经被一个 Ruby 脚本调用(它本身被另一个应用程序调用),我想我会尽可能多地在 AppleScript 中做。这一切的意义比仅仅检查应用程序是否正在运行要复杂一些。我也激活了它,检查它的窗口,然后敲击它。如果不是 GUI 脚本部分,我会坚持使用 Ruby。有问题的应用程序甚至是一个 Java 应用程序,所以没有深度的 AppleScript 支持——只有简单的窗口和击键的东西
    • 我应该补充一点,正是因为它有点脆弱,因为它是一个Java应用程序,所以我想尽可能地检查所有内容(例如,应用程序的名称是“ Processing”,但也是“JavaApplicationStub”,因为那是捆绑包中的实际应用程序 - 真是一团糟)。并且可以有多次安装应用程序(遗留原因),这就是我需要路径检查的原因。
    • 好吧,applescript 不会做你想做的事,所以使用 shell。您甚至可以从 ps 获取 pid,一旦您知道可以将该进程作为目标来运行其他命令...请参阅我的帖子以了解如何执行此操作...stackoverflow.com/questions/4666387/…
    • 感谢您的提示!不过,我已经提出了自己的解决方案 - 请参阅上面的更新问题
    【解决方案2】:

    我认为你需要做的就是:

    tell application "System Events"
        set theAlias to application file of item 1 of (processes whose bundle identifier is "com.apple.TextEdit")
        set thePath to (the POSIX path of theAlias)
    end tell
    

    无论如何,它似乎对我有用......

    【讨论】:

    • 是的,我在发布问题后也到了那里。但我不明白为什么我不能直接用那个别名做很多其他的事情。例如,为什么我不能执行“应用程序文件等于 [作为别名的路径] 的进程”之类的?我只想通过它的路径找到一个正在运行的应用程序
    • 或者那件事,我为什么不能processes whose (application file as text) equals "path:to:something"
    • 哎呀,我什至无法使用您的代码获取theAlias,然后执行processes whose application file is theAlias - 我只是得到一个空列表,即使我应该再次获取 TextEdit 进程。因此,换句话说,似乎没有可以通过以任何方式、形状或形式匹配application file 来过滤processes。它甚至不等于自己
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 2014-09-26
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    相关资源
    最近更新 更多