SCRIPT: Is App Installed

###MACRO:   Is App Installed

~~~ VER: 1.0    2017-01-06 ~~~

####DOWNLOAD:
@APP @TEST Does App Exist.kmmacros (3.5 KB)


###ReleaseNotes

  • The AppleScript in this macro determines if an app with a given bundle ID has been installed on your Mac.
  • It does this without causing the app to run, if it is installed.
  • Perhaps it is obvious to others, but I found it very hard to find a script that would do this.
  • REF:
    robjwells, http://stackoverflow.com/a/14360914/915019
  • In this TEST Macro/Script, I check for "BBEdit", which has a bundle ID of com.barebones.bbedit.
  • I hope you will find this helpful.
  • If you know of a better method, please post.

###AppleScript

try
  tell application "Finder" to get application file id "com.barebones.bbedit"
  set appExists to true
on error
  set appExists to false
end try

return appExists


EDIT: 2017-01-07 4:23 PM CT

You can use this script to get the Bundle ID:

set targetApp to "BBEdit"

set bundleID to get id of application targetApp
return bundleID

-->com.barebones.bbedit
1 Like

You might also be interested in this script Rob (@ComplexPoint) posted a number of years ago in the DEVONthink forum. (He can chime in, here, if he has updated this code.)

http://forum.devontechnologies.com/viewtopic.php?f=20&t=13230

Wouldn’t it be more useful to search for the application name? (Usually, when I don’t know if an app is installed, I don’t know the BundleID either.)

For that you could say

 id of application "application name"

Example:

try
  set theApp to "textmate"
  # Force-refresh database; for testing only
  do shell script "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -r -f -apps user,local,system"
  set theID to id of application theApp
  display alert "Application “" & theApp & "” is installed.\nBundleID: " & theID
on error
  display alert "No application “" & theApp & "” found!"
end try

Notes:

  • The “do shell script” force-refreshes the LaunchServices database for apps. (May take 30 seconds or so.) I have included it for testing, but for normal usage it should not be necessary, since the database gets auto-updated regularly.
  • The “on error … display alert” isn’t strictly necessary either. Normally, if the app is not found, you get the “Choose Application” window. However, in some occasions the “Choose Application” window does not show up.

Edit:

I refined the AppleScript a bit and wrapped it in a KM macro “Get Bundle ID”.

Go here to download.

1 Like

@Tom, thanks for the suggestion.

Yep, I always get the "Choose Application" window:

With my script, I don't see any adverse effects.

I suppose it depends on the situation/environment of the person writing the macro. In my case, I have the target app, "BBEdit", installed, but I want to use "TextWrangler" on any of my Macs where it is not installed, or where other users do not have BBEdit installed.

If you don't have the target app installed, and you are writing a macro, then I'm not sure I see a need for the test.

As you have shown, if you do have the target app installed, it is very easy to get the BundleID.

But for those cases where the author does not have the target app, then your approach provides an alternative if the author cannot determine the BundleID by other means.

Thanks for sharing.

Thanks for sharing.

That script looks more comprehensive, but also more complex.

IAC, I get an error when I run it:

error "System Events got an error: Can’t make missing value into type text." number -1700 from missing value to text

Hmmm. I’m running it on 10.11.6, if that makes a difference. Here’s my copy – just tried it over here in Script Debugger 6 and it executed correctly, FWIW.

    -- Provided by Houthakker (R Trew; Complex Point) 20140326.  PK.    

    property pTitle : "Tell application id ..."

        property pDefaultSearch : "dev"

        property pCodeCopy : "Copy creator code"
        property pBundleCopy : "Copy bundle identifier"
        property pNameCopy : "Copy app name"

        -- System Events
        on run
          tell application id "sevs"
            activate
            set strSearch to text returned of (display dialog "Enter part of application name:
           
        (or leave blank to see all running applications)" default answer pDefaultSearch with title pTitle)
          end tell
          
          handle_string(strSearch)
        end run

        on handle_string(strSearch)
          
          tell application id "sevs"
            
            if (strSearch ≠ "") and (strSearch ≠ "*") then
              -- the following failed in 10.9.2 20140326; changed the code to explicitly specify "missing value as string"
              -- set {lstCode, lstBundle, lstFile} to {creator type, bundle identifier, file} of (application processes where name contains strSearch and bundle identifier is not missing value)
              set {lstCode, lstBundle, lstFile} to {creator type, bundle identifier, file} of (application processes where name contains strSearch and bundle identifier is not (missing value as string))
              set strPrompt to "Applications with \"" & strSearch & "\" in their name:"
            else
              set {lstCode, lstBundle, lstName, lstFile} to {creator type, bundle identifier, name, file} of (application processes where bundle identifier is not (missing value as string))
              set strPrompt to "All currently running applications:"
            end if
            repeat with i from 1 to length of lstCode
              set varFile to item i of lstFile
              if varFile ≠ missing value then
                set strName to (name of item i of lstFile)
              else
                set strName to item i of lstName
              end if
              
              set item i of lstCode to item i of lstCode & "=" & item i of lstBundle & "=" & strName
            end repeat
            
            set my text item delimiters to linefeed
            set strApps to lstCode as string
            
            set lstApps to paragraphs of (do shell script "echo " & quoted form of strApps & " | sort -t '=' -k 3")
            if length of lstApps > 0 then
              set lstDefault to {first item of lstApps}
            else
              activate
              display alert "No running apps have names matching " & strSearch
              return
            end if
            activate
            set varChoice to choose from list lstApps with prompt strPrompt default items lstDefault with title pTitle
            
            if varChoice is false then return
            
            set my text item delimiters to "="
            set {strID, strBundle, strName} to text items 1 thru 3 of first item of varChoice
            
            set {blnCode, blnBundle, blnName} to {true, true, true}
            
            -- CREATOR CODE
            if strID ≠ "????" then
              set strCode to "tell application id \"" & strID & "\""
            else
              set blnCode to false
              set strCode to strName & " has no creator code ..."
            end if
            
            -- BUNDLE IDENTIFIER
            if strBundle ≠ "missing value" then
              set strBundle to "tell application id \"" & strBundle & "\""
            else
              set blnBundle to false
              set strBundle to strName & " has no bundle identifier"
            end if
            
            -- APPLICATION NAME
            if strName ends with ".app" then
              set strName to text 1 thru -5 of strName
              set strAppName to "tell application \"" & strName & "\""
            else
              set blnName to false
              set strAppName to ""
            end if
            
            
            set strChoice to "CREATOR CODE:    " & strCode & "

        BUNDLE IDENTIFIER:    " & strBundle & "

        APP NAME:    " & strAppName
            
            
            set lstBtns to {}
            if blnName then set end of lstBtns to pNameCopy
            if blnBundle then set end of lstBtns to pBundleCopy
            if blnCode then set end of lstBtns to pCodeCopy
            set lngButtons to length of lstBtns
            
            if lngButtons > 0 then
              set strClip to "-- " & strName & return
              activate
              set strBtn to (button returned of (display dialog strChoice buttons lstBtns default button lngButtons with title strName))
              if strBtn = pCodeCopy then
                set strClip to strClip & strCode
              else if strBtn = pBundleCopy then
                set strClip to strClip & strBundle
              else
                set strClip to strAppName
              end if
              set the clipboard to strClip & return & return & "end tell"
            else
              activate
              display alert strName & " is not a scriptable process"
            end if
            set my text item delimiters to space
          end tell
        end handle_string

Aah, OK, I got it now! LOL, I interpreted your topic as if it was to find out if an app is installed on a certain machine; in the sense of “find out for myself because I’m not sure”, not in the sense of “determining a given condition for KM which is already known to me”.

That’s why I said, for me it is more convenient to search an application by name instead of Bundle ID :open_mouth:

Sorry for misinterpreting your post!

No problem. I'm sure your solution will be of interest to some users, maybe more than mine. :wink:

At least now all KM users have a resource for checking for existance of an app.

BTW, I don’t have problems to remember the Bundle IDs of BBEdit and TextMate; but some others, yes :wink:

OK, your script runs fine for me also.

But I just discovered a deal-breaker:

It will list the codes for all the applications running on your system,

It lists ONLY those apps that are RUNNING, not just installed.

My need, and macro/script, checks to see if an app has been installed.

Thanks anyway.

1 Like