0
votes

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
2

2 Answers

1
votes

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
0
votes

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