且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我如何检查,当我有它的文件路径的应用程序正在运行?

更新时间:2023-10-20 15:44:10

我们有很多的Mac上的工具和你通常可以找到一个解决方案。你的情况我同意,你不能在应用程序文件进行筛选。你可以大概只有过滤的字符串,数字或布尔变量。

但我们确实有其他工具的命令行如,我们还可以使用Objective-C的方法。这里有一个命令行方式...

 设置applicationPosixPath为/应用程序/实用/ AppleScript的Editor.app尝试
    做shell脚本/斌/ PS -ef | grep按&放大器;引述applicationPosixPath和放大器形式; | grep的-v grep的
    回归应用程序运行
出错
    返回应用程序没有运行
年底试

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

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