I've found my devices using IOServiceGetMatchingServices
and got the property dictionary like this:
kernResult = IORegistryEntryCreateCFProperties(nextMedia,
(CFMutableDictionaryRef *)&props,
kCFAllocatorDefault, 0);
From that dictionary I can extract the informations for the icons:
NSString *bId = [props valueForKeyPath:@"IOMediaIcon.CFBundleIdentifier"];
NSString *rFile = [props valueForKeyPath:@"IOMediaIcon.IOBundleResourceFile"];
Those two give me this (as an example):
com.apple.iokit.IOStorageFamily (Bundle identifier) Internal.icns (Resource File)
I tried to extract the icon using this method:
NSBundle *bundleWithIcon = [NSBundle bundleWithIdentifier:bId];
NSString *iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];
But bundleWithIcon
is nil
.
Is this even the correct method to get the icon?
I think I have to somehow load the bundle to be able to load it with bundleWithIdentifier
, how can I do this?
PS: There's another question which (I think) tries to ask the same thing, but only asks for bundles, not if this is the correct way.
Just recently Andrew Myrick answered a similar question on the darwin-dev mailing list:
KextManagerCreateURLForBundleIdentifier()
in<IOKit/kext/KextManager.h>
may be of use, though I believe it only works for kexts that are either 1) loaded, or 2) in /S/L/E/. Here is the Snow Leopard headerdoc:/*! * @function KextManagerCreateURLForBundleIdentifier * @abstract Create a URL locating a kext with a given bundle identifier. * * @param allocator * The allocator to use to allocate memory for the new object. * Pass <code>NULL</code> or <code>kCFAllocatorDefault</code> * to use the current default allocator. * @param kextIdentifier * The bundle identifier to look up. * * @result * A CFURLRef locating a kext with the requested bundle identifier. * Returns <code>NULL</code> if the kext cannot be found, or on error. * * @discussion * Kexts are looked up first by whether they are loaded, second by version. * Specifically, if <code>kextIdentifier</code> identifies a kext * that is currently loaded, * the returned URL will locate that kext if it's still present on disk. * If the requested kext is not loaded, * or if its bundle is not at the location it was originally loaded from, * the returned URL will locate the latest version of the desired kext, * if one can be found within the system extensions folder. * If no version of the kext can be found, <code>NULL</code> is returned. */ CFURLRef KextManagerCreateURLForBundleIdentifier( CFAllocatorRef allocator, CFStringRef kextIdentifier);
Note that prior to Snow Leopard, it may only work for kexts in /S/L/E; the API existed, but there was no headerdoc describing its behavior.
For me this worked really well on Mac OS X 10.5.