views:

184

answers:

3

Is there any way to find out the .icns file an IconRef refers to or has been loaded from? Or even the id of the containing bundle if there is one?

I understand that not all icons are loaded directly from a file (composite icons for example) so this wouldn't work all the time.

The question I'm trying to answer is "Where does the icon the Finder would display for file X originate?" Note that I'm interested in the origin of the icon in the file system, not the icon's image data. As far as I can tell, the workings behind going from file path to icon - eg. GetIconRefFromFileInfo and NSWorkspace.iconForFile - are fairly opaque.

I'm open to undocumented/private solutions if that's what it takes.

@millenomi: Yes, avoiding Apple's icons is the point of the exercise.

A: 

That's because, once loaded, the system does not keep a reference to the icon file the icon came from.

Your best bet is to search for *.icns files in /System, unfortunately. Note that those icons are under Apple's copyright, and you shouldn't reuse them (except when loaded through their APIs).

millenomi
+1  A: 

Launch Services has private APIs for traversing its bundle registration database, and you can find the .icns files that way. You can view this information using the lsregister tool inside LaunchServices.framework/Support; use lsregister -dump to view the complete database.

Obligatory UndocumentedGoodness warning: If you use these functions, your app will break sooner or later. (And parsing the output of lsregister -dump is an even worse idea!)

Also, you seem to be aware of this but I'll point it out anyway: Not all icons come from a .icns file. Some are in resource files, such as in an old-style Carbon application. Another case is custom (pasted into the Finder's Info window) icons, which are one or more resources of ID -16455. (Classical icons are in multiple resources of types 'icl8', 'ics8', etc., whereas modern icons are in a single resource of type 'icns'.)

Unfortunately, I haven't played with this private API, so I can't be more specific.

Peter Hosey
Jarret Hardie
A: 

Answering myself...

The following doesn't accomplish the original question - finding out which file is behind an IconRef - but it does achieve my goal of avoiding Apple-owned icons without abandoning file-specific icons altogether.

The trick is to work out which application will open the file, and assume the file's icon will be supplied by that application.

Use LSGetApplicationForItem to find out which application would be used to open the file. If it's not an Apple application (check the bundle ID) I assume it's safe to use the file's icon (as returned by GetIconRefFromFileInfo).

There are also a few special cases I need to deal with - avoiding the generic document, folder, application and bundle icons as well as "special" folders like Documents and Music.

Adrian