当我知道应用程序的文件路径时,如何检查它是否正在运行?

发布于 2024-10-11 23:30:11 字数 2576 浏览 3 评论 0原文

我正在尝试制作一个脚本(除其他外)需要知道某个应用程序是否正在运行。为了获得最大的鲁棒性,我想通过它的文件路径找到它。或者,如果失败,请通过名称或包标识符找到它,然后检查其文件路径。只是为了让事情变得复杂,我有 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:
太棒了,但我无法将其与任何东西进行比较!我什至无法将应用程序文件别名转换为 POSIX 路径并将它们作为字符串进行比较。我也无法将 POSIX 路径转换为别名,然后进行比较。

那么,我该怎么办?

更新/解决方案

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

我可能应该更具体一点。正如我在下面的一些评论中所写的那样,当您只有路径时确定 an 是否正在运行并不是脚本应该做的全部事情。事实上,重点是找到与路径匹配的进程,然后执行一些 GUI 脚本。即,我无法使用简单的 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

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

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

But that doens't work...

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

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.

So, what do I do?

Update/solution

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

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).

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

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)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

辞旧 2024-10-18 23:30:11

我们在 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

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.

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
↙厌世 2024-10-18 23:30:11

我认为你需要做的就是:

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

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

I think all you need to do is this:

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

It seems to work for me, anyway...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文