Any way to change the icon of a non-app in Mavericks?

To fix a broken program for OSX 10.9 Mavericks, as recommended by a developer I’ve used a linux version & put together an applescript installer for it. This installer will be distributed to Maverick users instead of the standard one for OSX. The installed file that is to be opened is a .jar file. But I’ve been having headaches trying to get the icon to change to the program icon. Is there any technique for doing this with either Applescript or Unix or other way?
Jar files are not seen by the system as being executables & only used to start up the java executable file.

Having a java file icon in the dock (a cup of coffee) instead of the fox icon of the program looks confusing.

From what I’ve been able to find out, Mountain Lion & Mavericks have less abilities for icons (not to mention other user abilities.)

Not sure i am allowed to post external links to forums, but this is the issue here http://www.gnutellaforums.com/new-phex-users/102551-phex-crashing-macosx-mavericks.html#post373173
(scroll down from the forum rules)

Selet the xx.jar icon
command + i to open the info window
Select the original icon
paste the new one

Here is a script skeleton doing the trick :

--[SCRIPT colle_icone]

property cApplication : missing value

to copyPaste(cv)
	tell application "Finder"
		activate
		tell application "System Events"
			tell process "Finder"
				tell window 1
					keystroke tab -- select icon button
					keystroke (cv & "w") using command down -- (copy or paste) + close window
				end tell -- window 1
			end tell -- process Finder
		end tell
	end tell -- application System Events
	
end copyPaste

to CopyFinderIcon(sel)
	tell application "Finder"
		activate
		copy sel's item 1 to s
		open information window of (s as alias)
		my copyPaste("c")
	end tell -- Finder
end CopyFinderIcon

to PasteFinderIcon(sel)
	tell application "Finder"
		activate
		repeat with s in sel -- changed
			open information window of (s as alias) -- changed
			my copyPaste("v")
		end repeat
	end tell -- Finder
end PasteFinderIcon

on open (sel)
	
	-- copy current application to cApplication
	
	-- Comment and Uncomment these lines to test both functions.
	
	--CopyFinderIcon(sel)
	my PasteFinderIcon(sel)
	
	-- ---------------------------------------------------------	
	
	--tell application (name of cApplication) to activate
	
end open

--[/SCRIPT]

Due to Gatekeeper I’m not sure that for a one shot use such a script is really useful.

Yvan KOENIG (VALLAURIS, France) lundi 2 décembre 2013 10:55:58

Thanks Yvan. :slight_smile:

I cannot figure out how to use the script. I presumed I would need to specify the location of the file to copy icon from and the file to copy to. But the script won’t let me put those definitions in. Not sure a select specific file command would also be required with Events/Finder.

Ideally, this could be used in my installer script, ie: (1) after the application folder is installed but before the Aliases for either desktop or Dock are processed. (2) Icon is copied from the applet within the installer app. or the installer app itself and then copied to the .jar file a few levels down in the application folder. (Since .icns files have a generic icon, instead the installer app’s icon would probably be best.)

Sorry I’m not too clever with scripting. (blush)

My fault.

I missed the fact that the .scpt file was not the final version saved as an application.

--[SCRIPT colle_icone]

property cApplication : missing value

to copyPaste(cv)
	tell application "Finder"
		activate
		tell application "System Events"
			tell process "Finder"
				tell window 1
					keystroke tab -- select icon button
					keystroke (cv & "w") using command down -- (copy or paste) + close window
				end tell -- window 1
			end tell -- process Finder
		end tell
	end tell -- application System Events
	
end copyPaste

to CopyFinderIcon(sel)
	tell application "Finder"
		activate
		copy sel's item 1 to s
		open information window of (s as alias)
		my copyPaste("c")
	end tell -- Finder
end CopyFinderIcon

to PasteFinderIcon(sel)
	tell application "Finder"
		activate
		repeat with s in sel -- changed
			open information window of (s as alias) -- changed
			my copyPaste("v")
		end repeat
	end tell -- Finder
end PasteFinderIcon

on open (sel)
	if cApplication is missing value then
		copy current application to cApplication
		CopyFinderIcon(sel)
	else
		my PasteFinderIcon(sel)
		tell application (name of cApplication) to activate
	end if
end open

--[/SCRIPT]

Save it as an application.

Drag and drop the file wearing the icon to apply on the script.app
then drag and drop the target file onto the same script.app.

The first step will fill the clipboard with the wanted icon
the second step will paste the icon into the target file.

Yvan KOENIG (VALLAURIS, France) mardi 3 décembre 2013 15:33:17

The icon app runs perfectly in Snow Leopard, but not for Mavericks. At least not for the .jar file. I tried changing Finder view options and a few system restarts. Also tried on the jar file when not in apps folder, and also open in 32-bit.

Edit: I saved the script in Mavericks as an app and it worked! :wink: I guess that suggests some incompatibility between Snow Leopard’s Script apps and Maverick’s Script apps.

Would there be a way to adjust the script to seek specific files on the drive rather than use drag & drop?
In that way I could hopefully incorporate it into the installer. ie: copy the installer’s icon & copy to the .jar file in the app folder.

I used the script under Leopard, Snow Leopard, Lion, Mountain Lion and now Mavericks.

Here is an extended one which may also be used from the script editor or by double click if it’s saved as application.
This way you have all what you need for your project.

--[SCRIPT colle_icone]

property cApplication : missing value

on run
	tell application "SystemUIServer" to set source to choose file with prompt "Select the file wearing the wanted icon"
	tell application "Finder" to select source
	copy current application to cApplication
	my CopyFinderIcon({source})
	tell application "SystemUIServer" to set targetFile to choose file with prompt "Select the file to apply the icon to"
	tell application "Finder" to select targetFile
	my PasteFinderIcon({targetFile})
	tell application (name of cApplication) to activate
end run


to copyPaste(cv)
	tell application "Finder"
		activate
		tell application "System Events"
			tell process "Finder"
				tell window 1
					keystroke tab -- select icon button
					keystroke (cv & "w") using command down -- (copy or paste) + close window
				end tell -- window 1
			end tell -- process Finder
		end tell
	end tell -- application System Events
	
end copyPaste

to CopyFinderIcon(sel)
	tell application "Finder"
		activate
		copy sel's item 1 to s
		open information window of (s as alias)
		my copyPaste("c")
	end tell -- Finder
end CopyFinderIcon

to PasteFinderIcon(sel)
	tell application "Finder"
		activate
		repeat with s in sel -- changed
			open information window of (s as alias) -- changed
			my copyPaste("v")
		end repeat
	end tell -- Finder
end PasteFinderIcon

on open (sel)
	if cApplication is missing value then
		copy current application to cApplication
		CopyFinderIcon(sel)
	else
		my PasteFinderIcon(sel)
		tell application (name of cApplication) to activate
	end if
end open

--[/SCRIPT]

Yvan KOENIG (VALLAURIS, France) mardi 3 décembre 2013 20:54:05

Thank you Yvan that’s an excellent script for the purpose. :slight_smile:

I am guessing it does not need error handlers?

I’m most of the way there to what I wanted. ie: icon changing without need for user selection. The destination of the icon is easy since the jar file will already be installed before the icon changing. However, is there a method of finding the position of the installer and including that within the handler to set the source of the icon?

The only alternative I can think of which is a little sloppy is to install a temporary file with the necessary icon into the Applications folder (or user documents folder) and use that file as the source icon, then delete that file at end of installation.

The way I have tested it is to install the folder of the application, then launch & run the icon script from within the installer’s resource folder to change the icon. Then returns to the main script and the Dock/Desktop Alias section is run.

  • Edit: I eventually managed to get the handler to work ‘within’ the script instead of calling an external script. :smiley: But ability to find location of installer would be very handy. :wink:

Edit-2: I’m guessing there is something wrong with this?

	tell application "SystemUIServer" to set source to ((my POSIX file (front document's path) as string) & "P installer.app") as alias

OK I don’t know Mavericks at all but an icon should lay as a .icns file in the package (Contents>Resources>) or am I missing sth? I don’t think the icon need to be added afterwards in some way or another. Unless all is different in Mavericks?

True for .app files. But the program being installed and will be used for launching is not an .app file but instead a .jar file. The actual executable file is the java executable which will have its own java icon but that’s unavoidable in this situation. To overcome a broken MacOSX app program when run in Mavericks the process is being by-passed by launching java directly with the .jar file. The idea is to have the .jar file’s alias in the Dock or Desktop with the original program’s icon (a fox) so people instantly recognise it. (The generic coffee cup icon of jar files is highly confusing for others.) :wink:

The .jar file is a couple of levels down inside of the program folder. /Applications/p_3.4.2.163/lib/p.jar

Unfortunately the MacOSX developer of the app no longer uses MacOSX, instead linux. So a redoing of the OSX app itself is unlikely in near future unless someone who knows java programming volunteers.
This particular program has always been free and ‘Open Source’.

I don’t know your entire code so I can’t tell you how you may get the path of the source file.
If the script is stored as an application you may put the file wearing the icon in it’s own package.
It’s what is assumed in the attached version.


on run
	my main()
end run

on main()
	copy current application to cApplication
	set myPath to path to me as text
	set source to myPath & "Contents:fileWithIcon"
	my CopyFinderIcon({source})
	# Edit the next instruction to fit your needs
	# tell application "SystemUIServer" is just used to bring the choose file dialog at front
	tell application "SystemUIServer" to set targetFile to choose file with prompt "Select the file to apply the icon to"
	tell application "Finder" to select targetFile
	my PasteFinderIcon({targetFile})
	
	tell application (name of cApplication) to activate
end main

to copyPaste(cv)
	tell application "Finder"
		activate
		tell application "System Events"
			tell process "Finder"
				tell window 1
					keystroke tab -- select icon button
					keystroke (cv & "w") using command down -- (copy or paste) + close window
				end tell -- window 1
			end tell -- process Finder
		end tell
	end tell -- application System Events
	
end copyPaste

to CopyFinderIcon(sel)
	tell application "Finder"
		activate
		copy sel's item 1 to s
		open information window of (s as alias)
		my copyPaste("c")
	end tell -- Finder
end CopyFinderIcon

to PasteFinderIcon(sel)
	tell application "Finder"
		activate
		repeat with s in sel -- changed
			open information window of (s as alias) -- changed
			my copyPaste("v")
		end repeat
	end tell -- Finder
end PasteFinderIcon

Yvan KOENIG (VALLAURIS, France) mercredi 4 décembre 2013 12:02:16

Thanks again Yvan, highly appreciated for your help. :slight_smile:

I haven’t tried your script yet. I’m just looking at how to work it in now. It’s not dramatically different to what was there.

First part of the installer script program deals with setting up a settings folder & installing some base settings & a connection file.
The 2nd part deals with installing the folder of the program & at end of same tell block the handler is included. After the tell block the handler is defined.
The section after this deals with Dock or Desktop alias. And last section finishes off with option to launch the program via the jar file, quit or visit the support website.

This is what i had, starting from the app folder installation section:

tell application "Finder"
	
	try
		duplicate my pfold to apps_path with replacing --- installs p app folder and replaces any such folder already there
	end try
	
	try
		my iconwork() --- forwards to icon handler
	end try
	
end tell


--[SCRIPT colle_icone]

on iconwork()
	tell application "SystemUIServer" to set source to .... -- (I was using a set location of the installer for testing. This is where I was looking for an alternative approach to get the location of the installer regardless of where it might be on someone's system/server)
	copy current application to cApplication
	my CopyFinderIcon({source})
	tell application "SystemUIServer" to set targetFile to (((path to applications folder from local domain) as string) & "p_3.4.2.163:lib:p.jar") as alias
	tell application "Finder" to select targetFile
	my PasteFinderIcon({targetFile})
	tell application (name of cApplication) to activate
end iconwork


to copyPaste(cv)
	tell application "Finder"
		activate
		tell application "System Events"
			tell process "Finder"
				tell window 1
					keystroke tab -- select icon button
					keystroke (cv & "w") using command down -- (copy or paste) + close window
				end tell -- window 1
			end tell -- process Finder
		end tell
	end tell -- application System Events
end copyPaste

to CopyFinderIcon(sel)
	tell application "Finder"
		activate
		copy sel's item 1 to s
		open information window of (s as alias)
		my copyPaste("c")
	end tell -- Finder
end CopyFinderIcon

to PasteFinderIcon(sel)
	tell application "Finder"
		activate
		repeat with s in sel -- changed
			open information window of (s as alias) -- changed
			my copyPaste("v")
		end repeat
	end tell -- Finder
end PasteFinderIcon

on open (sel)
	if cApplication is missing value then
		copy current application to cApplication
		CopyFinderIcon(sel)
	else
		my PasteFinderIcon(sel)
		tell application (name of cApplication) to activate
	end if
end open

--[/SCRIPT]
--- after this dialog with options for creating an Alias for Dock (default button), Desktop or None. (in this scenario for this installer, choosing None is not recommended.)
--- If installing Dock icon, I always force the installer to be the front-most app so the installation process continues smoothly

I’ll post back to say how things go with your later script update.

Didn’t quite work like I hoped. ie: grabbing the icon from the active installer. But a workaround is to set an app inside the resource folder with the icon which will have the same effect. :slight_smile:

It works fine with a mini-script app inside the installer resource folder.

One last question, is there a way to close the folder after applying the icon?
As it is, the lib folder of the program folder is left open. This might leave some people confused as to what it is (except for the icon of course.)

It’s strange, some things compile happily with Applescript 2.3 on Snow Leopard but refuse to compile on Applescript 2.6 on Mavericks. And it does not show you where the error is, unlike AS2.3.

Edit again, sorry AS was just being a pain. After restarting AS it behaved properly. Figured out the close window, yes I know basic. :smiley:

I apologize but I have no way to guess where is the script stored.
So I can’t design a code grabbing the icon from the installer itself.
If the script is included in a larger script used as installer it’s quite a trivial task.
set source to path to me would do the trick.

Yvan KOENIG (VALLAURIS, France) jeudi 5 décembre 2013 08:38:20

wow that was so simple. :smiley: Works a charm thank you again.