Detect Version of Application

How could I detect which version of a program is installed if any?

in most of the cases this is sufficient

version of application "myApplication"

I don’t know if that would work. The code I’m using would work in any of the Adobe Photoshop CS (1,2,3) applications. Could I change my tell commands dynamically based on which is installed, and alert the user if none are installed?

I tried this:


	set PS to {"Adobe Photoshop CS3", "Adobe Photoshop CS2", "Adobe Photoshop CS"}
	set PSversion to "Photoshop not installed."
	repeat with i from 1 to (count PS)
		try
			set PSversion to item i of PS & " " & (version of application (item i of PS))
			exit repeat
		end try
	end repeat
	display dialog PSversion as string

But Script editor still opens a dialog asking where the applications are that it did not find. How do I tell it to ignore that?

I think what you want to to find out what versions you are available so you know which one to target… I think there will be more work down the line but this was a fun challenge for me so here’s what I came up with


set Photoshops to {}
set Versions to {}

set appList to do shell script "ls  /Applications/*/Adobe* | grep \"app\""

set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
repeat with i from 1 to count of text items in appList
	if text item i of appList contains "Adobe Photoshop" then copy text item i of appList to end of Photoshops
end repeat
set AppleScript's text item delimiters to tid

repeat with aShop in Photoshops
	
	set appVersion to text items -6 through -8 of aShop as string
	copy appVersion to end of Versions
end repeat

return Versions

MM

Wow, nice.

One element I don’t understand is the shell script. What is it getting?

Also, I have CS3 installed on the machine I’m using currently. When I return Versions into a dialog like this:


	set myString to ""
	repeat with i from 1 to count Versions
		set myString to myString & "(" & i & ") " & item i of Versions
		if i is not (count Versions) then set myString to myString & return
	end repeat
	display dialog myString

I get:

I wonder where the “ter” came from? Maybe “Adobe DNG Converter”?

I’m not a pro coder, so this could probably be refined, but it seems to work. It uses text item delimiters to filter out everything instead of assuming that all versions have the same number of characters in the name.


on run
	set myAdobes to {}
	set myPhotoshops to {}
	
	-- find Adobe apps in the Applications folder
	set appList to do shell script "ls /Applications/*/Adobe* | grep \"app\""
	
	-- put Adobes into list
	set tid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to return
	repeat with i from 1 to count of text items in appList
		set theApp to trim(text item i of appList, "/", "end")
		copy trim(theApp as string, ".", "ext") to end of myAdobes
		if theApp contains "Photoshop" then ¬
			copy my trim(theApp as string, ".", "ext") to the end of myPhotoshops
	end repeat
	set AppleScript's text item delimiters to tid
	
	-- display
	set myString to "Adobe:" & return
	if myAdobes is {} then
		set myString to myString & "(none)"
	else
		repeat with i from 1 to count myAdobes
			set myString to myString & i & ". " & item i of myAdobes
			if i is not (count myAdobes) then set myString to myString & return
		end repeat
		set myString to myString & return & return & "Photoshop:" & return
	end if
	if myPhotoshops is {} then
		set myString to myString & "(none)"
	else
		repeat with i from 1 to count myPhotoshops
			set myString to myString & i & ". " & item i of myPhotoshops
			if i is not (count myPhotoshops) then set myString to myString & return
		end repeat
	end if
	display dialog myString
end run

on trim(t, d, func)
	set tid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	if (count text items of t) > 1 then
		if func is "ext" then set t to text 1 thru text item -2 of t
		if func is "end" then set t to text item -1 of t
	end if
	set t to text items of t
	tell t to set t to beginning & ({""} & rest)
	set AppleScript's text item delimiters to tid
	return t
end trim

Looks like you got what you wanted and I take it you figured out what the shell script is doing.

Very nice work on cleaning it up !

MM

Thanks for the help!

A bit late but…
How does this work for you.

set appList to paragraphs of (do shell script "ls /Applications/*/Adobe* | grep \"app\"")
set biglistP to {"Photoshop:" & return as string}
set biglistA to {"Adobe:" & return as string}
repeat with i from 1 to number of items in appList
	set this_item to item i of appList
	if last character of this_item is ":" then
		set t to characters 1 thru -2 of (do shell script " basename " & quoted form of (this_item)) as string
	else
		set t to (do shell script " basename " & quoted form of (this_item)) as string
	end if
	set PSversion to t & " " & (version of application (t))
	if PSversion contains "Photoshop" then
		set item 1 of biglistP to (item 1 of biglistP & return & PSversion as string)
	else
		set item 1 of biglistA to (item 1 of biglistA & return & PSversion as string)
	end if
end repeat

display dialog item 1 of biglistP & return & return & item 1 of biglistA buttons {"OK"} default button 1

I was just including all Abobe programs for fun, all I really wanted to know was Photoshop. Given this, could the “basename” shell script and the shell script at the beginning be combined to make it even more minimal?

Hi,

assuming all Photoshop versions are located in /Applications/ and its own Adobe Photoshop xxx folder,
this gives you a list of the names of all existing versions


set PhotoShopList to paragraphs of (do shell script "ls /Applications/*/Adobe* | grep Photoshop | cut -d '/' -f 3")

Using Stefan’s shell script, I get two programs listed. I’m guessing it’s the DNG Converter showing up again (there are two apps in the “Adobe Photoshop CS3” folder, the converter and the actual Photoshop app).


	set myPhotoshops to paragraphs of (do shell script "ls /Applications/*/Adobe* | grep Photoshop | cut -d '/' -f 3")

        -- display
	set myString to ""
	repeat with i from 1 to count myPhotoshops
		set myString to myString & i & ". " & item i of myPhotoshops & return
	end repeat
	display dialog myString

Shell scripts look like a foreign language to me, so I would have no idea to change it.

This works on mine, but man is i t tortured :smiley:
There should be a way to trim it…

set myPhotoshops to paragraphs of (do shell script "find /Applications/  -maxdepth 1 -type d -name *Photoshop* -print0 | xargs -0 ls -F |grep Photoshop |grep \"/\"|grep -v \":\" |cut -d '/' -f 1")
-- display
set myString to ""
repeat with i from 1 to count myPhotoshops
	set this_item to item i of myPhotoshops
	set item i of myPhotoshops to this_item & ":  version:" & (version of application (this_item))
	set myString to myString & i & ". " & item i of myPhotoshops & return
end repeat
display dialog myString

Now for the second part: choosing which Application to use if multiple versions are installed. This is the main reason I need this script… where I work, some machines have multiple versions, some just have one or the other.

Because I don’t know shell script, I have no idea what mark’s script (previous post to this) does, or how universal it would be. So, for now, I’m sticking with mcgrailm’s original shell script (nearest the top).

The only way I can think of to choose the most recent version is to make a hash with the version as the key, and sort by the key. My problem now is that I don’t know how to sort a hash by the key in AppleScript. Anybody know how to do that?

Here’s what I have:


on run
	-- find Adobe apps in the Applications folder
	set appList to do shell script "ls /Applications/*/Adobe* | grep \"app\""
	set appList to paragraphs of appList
	set myPhotoshops to {}
	repeat with theApp in appList
		set theApp to trim(theApp as string, "/", "end") -- trim out everything but the app filename
		if theApp contains "Photoshop" then
			set theApp to my trim(theApp as string, ".", "ext") -- trim the extension
			set theVersion to version of application theApp
			set theVersion to my trim(theVersion, ".", "beg") -- trim everything but the first number of the version
			set theVersion to my trim(theVersion, " ", "end") -- if there is anything before the version number, trim it
			set theHash to {theVersion, theApp}
			copy theHash to the end of myPhotoshops
		end if
	end repeat
	
	-- display
	set myString to "Photoshop:" & return
	if myPhotoshops is {} then
		set myString to myString & "(none)"
	else
		repeat with aShop in myPhotoshops
			set myString to myString & item 1 of aShop & " " & item 2 of aShop & return
		end repeat
	end if
	display dialog myString
end run

on trim(t, d, func)
	set tid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	if (count text items of t) > 1 then
		if func is "ext" then set t to text 1 thru text item -2 of t
		if func is "end" then set t to text item -1 of t
		if func is "beg" then set t to text item 1 of t
	end if
	set t to text items of t
	tell t to set t to beginning & ({""} & rest)
	set AppleScript's text item delimiters to tid
	return t
end trim

Hi,

this does the same as your script


set myPhotoshops to paragraphs of (do shell script "ls /Applications/*/Adobe* | grep Photoshop | cut -d '/' -f 4 | grep Photoshop | cut -d '.' -f 1")

set myString to {}
set {TID, text item delimiters} to {text item delimiters, "."}
repeat with oneApp in myPhotoshops
    set end of myString to text item 1 of (version of application (oneApp) as text) & space & contents of oneApp
end repeat
set text item delimiters to return
set myString to myString as text
set text item delimiters to TID
display dialog myString

Explanation of the shell script:

ls /Applications/*/Adobe*

lists all entries in all subfolders of /Applications whose name begins with “Adobe” (result are paths)

 grep Photoshop

filters all paths which contains “Photoshop”
/Applications/Adobe Photoshop CS3/Adobe DNG Converter.app:
/Applications/Adobe Photoshop CS3/Adobe Photoshop CS3.app:

cut -d '/' -f 4

cuts the fourth field separated by slashes
Adobe DNG Converter.app:
Adobe Photoshop CS3.app:

grep Photoshop

filters only the Photoshop apps
Adobe Photoshop CS3.app:

 cut -d '.' -f 1"

cuts the first field separated by dots
Adobe Photoshop CS3

Thank you much Stefan.

Why does this line of code require the application to be active sometimes but sometimes not?

version of application "myApplication"

Hi,

here a different approach without causing any application to launch



set myPhotoshops to paragraphs of (do shell script "ls /Applications/*/Adobe* | grep Photoshop")
set myString to {}
set {TID, text item delimiters} to {text item delimiters, "."}
repeat with i in myPhotoshops
	set infoPlist to text 1 thru -2 of contents of i & "/Contents/Info"
	try
		set theName to do shell script "defaults read " & quoted form of infoPlist & " CFBundleExecutable"
		set theVersion to do shell script "defaults read " & quoted form of infoPlist & " CFBundleVersion"
		if theName contains "Photoshop" then set end of myString to text item 1 of theVersion & space & theName
	end try
end repeat
set text item delimiters to return
set myString to myString as text
set text item delimiters to TID
display dialog myString

Very Nice Stefan, :slight_smile:

Below is a quick edit to open the app of choice. It should open the correct version as its using the path found for each app.
Also I change the search to Photoshop, I have ‘Application/Adobe Photoshop Elements 2/Photoshop Elements 2.0’, which was not found if I hadAdobe*


set text item delimiters to ""
set myPhotoshops to paragraphs of (do shell script "ls /Applications/*/*Photoshop* | grep Photoshop")

set myString to {}
set myPath to {}
set {TID, text item delimiters} to {text item delimiters, "."}
repeat with i in myPhotoshops
	set infoPlist to text 1 thru -2 of contents of i & "/Contents/Info"
	set theAppPath to text 1 thru -2 of contents of i
	try
		set theName to do shell script "defaults read " & quoted form of infoPlist & " CFBundleExecutable"
		
		if theName contains "Photoshop" then
			set theVersion to do shell script "defaults read " & quoted form of infoPlist & " CFBundleVersion"
			set end of myString to text item 1 of theVersion & space & theName
			set end of myPath to {theAppPath, last item of myString}
		end if
	end try
end repeat
set text item delimiters to return
set text item delimiters to TID
set App_Choice to (choose from list myString with prompt "Which Appdo you want?" without multiple selections allowed) as text
if App_Choice is not "false" then
	
	repeat with i from 1 to number of items in myPath
		set this_item to item 2 of item i of myPath
		if this_item is App_Choice then
			open item 1 of item i of myPath
			exit repeat
		end if
	end repeat
end if

Reading this old post. This is pretty cool. Gets the version of PhotoShop that are installed on your machine.

I was trying to figure if there was a way to go one step further and write code for specific versions. The roadblock seems to come in where if I have two sections - one for PhotoShop CS3 and one for CS4 - and the user only has CS4 on their Mac then the script will prompt with a “Where is app Adobe PhotoShop CS3” message. If I use the code in this post to pull the name of the app in a variable and then say “Tell Application variablename” then the script can’t compile. If I put in “Using terms from Adobe PhotoShop CS3” then we are back where we started with the user prompt if they don’t have CS3 on their Mac.

My situation is that we have CS3 now, we are getting CS4 and will be installing it on Macs that already have CS3 (and we are leaving both on there) and any new Macs are going to only have CS4 on them. I was hoping to make one “universal” script that would run on any of those scenarios but it looks like that is not possible.

Anyone figured out a way to do this before??

Model: iMac Intel 10.5.8
Browser: Firefox 3.0.2
Operating System: Mac OS X (10.5)