当我有文件路径时,如何检查应用程序是否正在运行? [英] How do I check that an application is running when I have its file path?

查看:21
本文介绍了当我有文件路径时,如何检查应用程序是否正在运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a script (among other things) need to know if a certain application is running. For maximum robustness, I'd like to find it by its filepath. Or, failing that, find it by its name or bundle identifier, and check its filepath. Just to complicate things, I have the app path in POSIX form

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

What I want to do is something like this (using TextEdit as an example here)

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

但这不起作用...

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

I'm no AppleScript genius but I've found that I can at least find a running process from its bundle identifier, and then get its file as a useless "alias":

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

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

I get alias Macintosh HD:Applications:TextEdit.app:
Great, except I can't compare that to anything! I can't even translate that application file-alias to a POSIX path and compare them as strings. Nor can I translate the POSIX path I have into an alias, and then compare.

那我该怎么办?

感谢 Paul R 和 regulus6633 提供有用的提示!

Hat-tips to Paul R and regulus6633 for giving useful hints!

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

I should probably have been a little more specific. As I write in some comments below, figuring out if an is running when you only have its path isn't all the script should do. The point is in fact to locate the process that matches the path, and then do some GUI scripting. I.e. I can't use a simple ps because I need access to the GUI/AppleScript stuff (specifically the process' windows).

从技术上讲,我可以执行 ps 来获取 PID(如下面的 regulus6633 建议),但是 AppleScript 已经在由在另一个 shell 中运行的 Ruby 脚本生成的 shell 中运行,而且看起来凌乱.

I could technically do a ps to get the PID (as regulus6633 suggests below), but the AppleScript is already running in a shell spawned by a Ruby script running in another shell, and it just seemed messy.

最终这样做了(看起来很多,但在我所做的事情的背景下是必要的):

Ended up doing this (which seems like a lot, but it was necessary in the context of what I was doing):

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)

Note that the posixPath argument must be the path to the application's bundle (e.g. "/Applications/TextEdit.app/" with or without trailing slash) and not the actual executable file inside the bundle.
The function will return the process matching the given POSIX path (or null if it's not found)

bundleIdentifier 参数不是必需的,但它通过缩小进程列表大大加快了一切.如果您希望仅使用路径就可以工作,您可以这样做

The bundleIdentifier argument isn't necessary, but it speeds everything up a lot by narrowing the list of processes. If you want this to work just using the path, you can do this

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

推荐答案

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

We have lots of tools on the Mac and you can usually find a solution. In your case I agree that you cannot filter on the "application file". You can probably only filter on strings, numbers, or bools.

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

However we do have other tools such as the command line and we also have access to objective-c methods. Here's a command line method...

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

这篇关于当我有文件路径时,如何检查应用程序是否正在运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆