A Macro to Get OS Information and KM Version?

Warning: This is gonna get nerdy.

On the Mac, if you go to Safari, and then choose the Safari » About Safari Menu shown here:

Safari About

You will see this:

The first number (“14.1.2” in this case) is the “Version Number” as most people think of it.

The second number (16611.3.10.1.6) is often referred to as the Build Number, and it’s often not something most people need to or want to know about.

Technically, the first number here is called the CFBundleShortVersionString and the second is called the CFBundleVersion.

You can easily check either using the command-line tool defaults read like so:

defaults read "/Applications/Safari.app/Contents/Info" CFBundleShortVersionString

and/or

defaults read "/Applications/Safari.app/Contents/Info" CFBundleVersion

(Both of those are single-line commands, even if they appear “wrapped” here).

You can replace “Safari.app” with just about any other app to get that app’s information. That will work for the vast majority of the apps you will find.

Some apps (including Keyboard Maestro) put the version number in both fields. That’s “less common, but not unusual” if you follow me.

Some apps just use the CFBundleShortVersionString but that is rare. More often you’ll find the information is in both fields.

Some apps just use the CFBundleVersion and have no CFBundleShortVersionString at all, but this is very rare.


Note: Most of Apple's Built-In Apps Aren't Actually in /Applications/ Anymore

Recent versions of macOS include standard apps which appear in /Applications/ but aren't actually in /Applications/. For example, TextEdit.app will appear in /Applications/ but if you try

defaults read "/Applications/TextEdit.app/Contents/Info" CFBundleShortVersionString

You will get an error like this:

The domain/default pair of (“/Applications/TextEdit.app/Contents/Info”, CFBundleShortVersionString) does not exist

If that happens, use /System/Applications/ instead of just /Applications/.

The same is true for applications which appear in /Applications/Utilities/ such as Activity Monitor.app which is actually found at /System/Applications/Utilities/Activity Monitor.app

If you are trying to use one of these apps and are not sure where it is located, the easiest way to find out is to open a Terminal.app window and drag the app to it. That will reveal the actual path that you need to use. Just don't forget to make sure you add /Contents/Info after the .app!

2 Likes

Hi @tjluoma,

Thank you very much for your post. It is very educational and very helpful!!! I learned something new today.

Hey Guys,

Generally it's a very bad idea to hard-code paths – except when absolutely necessary or for one-off type scripts.

You can find any app on macOS (that I know of) using this construct (AppleScriptable or not):

# Calculator is NOT scriptable.
tell application "Calculator"
   # Alias to the app (HFS file path).
   set appPath to path to it
   # Normally the short version.
   set appVersion to version
end tell

You can transform the alias into a POSIX Path thus:

set appPathPosix to POSIX path of appPath

Locating apps is possible using Spotlight in the shell as well:

mdfind -onlyin / 'kMDItemFSName == "Calculator.app"c'
mdfind -onlyin / 'kMDItemCFBundleIdentifier == "com.apple.calculator"'

And I also have some AppleScriptObjC code for this sort of thing:

--------------------------------------------------------
# Auth: Christopher Stone <scriptmeister@thestoneforge.com>
# dCre: 2017/02/24 02:07
# dMod: 2021/08/19 19:16
# Appl: AppleScriptObjC
# Task: Application Version String Plus System Version String (best).
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @ASObjC, @Application, @Version, @String, @System, @Best
--------------------------------------------------------
use framework "Foundation"
use framework "AppKit"
use framework "Foundation"
--------------------------------------------------------

set appID to "com.stairways.keyboardmaestro.editor"

--------------------------------------------------------

set appNSURL to current application's NSWorkspace's sharedWorkspace()'s URLForApplicationWithBundleIdentifier:appID
set appBundle to current application's NSBundle's bundleWithURL:appNSURL
set appName to (appBundle's infoDictionary()'s objectForKey:"CFBundleName") as text
set appVer to (appBundle's infoDictionary()'s objectForKey:"CFBundleShortVersionString") as text
set appBundleVer to (appBundle's infoDictionary()'s objectForKey:"CFBundleVersion") as text
set sysVer to (current application's NSProcessInfo's processInfo()'s operatingSystemVersionString())
set sysVer to (sysVer's stringByReplacingOccurrencesOfString:("Version") withString:"macOS")
set sysVer to (sysVer's stringByReplacingOccurrencesOfString:("Build ") withString:"") as text
set infoString to appName & space & appVer & " (" & appBundleVer & ") on " & sysVer

return infoString

--------------------------------------------------------

-Chris

2 Likes