我发现我的设备使用IOServiceGetMatchingServices
并获得了这样的属性字典:
kernResult = IORegistryEntryCreateCFProperties(nextMedia,
(CFMutableDictionaryRef *)&props,
kCFAllocatorDefault, 0);
从那本词典中我可以提取图标的信息:
NSString *bId = [props valueForKeyPath:@"IOMediaIcon.CFBundleIdentifier"];
NSString *rFile = [props valueForKeyPath:@"IOMediaIcon.IOBundleResourceFile"];
这两个人给我这个(作为例子):
com.apple.iokit.IOStorageFamily (Bundle identifier) Internal.icns (Resource File)
我尝试使用此方法提取图标:
NSBundle *bundleWithIcon = [NSBundle bundleWithIdentifier:bId];
NSString *iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];
但bundleWithIcon
为nil
。
这是获取图标的正确方法吗?
我想我必须以某种方式加载捆绑包以便能够使用bundleWithIdentifier
加载它,我该怎么做?
PS:There's another question(我认为)试图问同样的事情,但只要求捆绑,而不是这是正确的方式。
答案 0 :(得分:7)
您可以使用NSWorkspace 初始图像为32x32,但它具有其他尺寸的表示,并将相应缩放
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
NSImage * icon = [ws iconForFile:@"/Volumes/Whatever"];
NSLog(@"%@", [icon representations]); // see what sizes the icon has
icon.size = NSMakeSize(512, 512);
答案 1 :(得分:2)
刚刚在darwin-dev邮件列表上Andrew Myrick answered a similar question:
KextManagerCreateURLForBundleIdentifier()
在<IOKit/kext/KextManager.h>
可能是 使用,虽然我相信它只有作用 对于1)加载的kexts, 或2)在/ S / L / E /。这是雪 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);
请注意,在Snow Leopard之前,它 可能仅适用于/ S / L / E中的kexts;该 API存在,但没有 headerdoc描述了它的行为。
对我而言,这在Mac OS X 10.5上运行得非常好。
答案 2 :(得分:1)
在玩'ioreg'命令时,我发现了一些让我想起你的问题,所以我会发布它:
尝试发出以下命令:
ioreg -c IOMedia -x
这将产生一大堆输出,看起来像这样:
| +-o IOBlockStorageDriver <class IOBlockStorageDriver, registered, matched, active, busy 0, retain 7>
| +-o Apple read/write Media <class IOMedia, registered, matched, active, busy 0, retain 9>
| | {
| | "Removable" = Yes
| | "BSD Unit" = 0x4
| | "IOBusyInterest" = "IOCommand is not serializable"
| | "BSD Minor" = 0xc
| | "Ejectable" = Yes
| | | "BSD Name" = "disk4"
| | "Leaf" = No
| | "IOMediaIcon" = {"CFBundleIdentifier"="com.apple.iokit.IOStorageFamily","IOBundleResourceFile"="Removable.icns"}
| | "Preferred Block Size" = 0x200
| | "Whole" = Yes
| | "Open" = Yes
| | "Size" = 0x100000
| | "Writable" = Yes
| | "Content" = "Apple_partition_scheme"
| | "IOGeneralInterest" = "IOCommand is not serializable"
| | "Content Hint" = ""
| | } | "BSD Major" = 0xe
这一切都让我相信(因此盲目地建议您进行调查)如果您遍历与“IOMedia”匹配的io注册表树,您可以获得包含键入“IOMediaIcon”的条目的属性字典,该条目本身就会出现成为一个集合,通知您捆绑标识符和资源文件名。
不要说这很容易......但请查看 FireWire SDK 以获取您可能需要的所有示例代码... 在任何情况下,它可能比硬编码预填充路径“更好”(在未来的OS版本中可能会消失)。
| K&LT;
答案 3 :(得分:0)
这两个人给我这个(作为例子):
com.apple.iokit.IOStorageFamily(Bundle identifier) Internal.icns(资源文件)
我尝试使用此方法提取图标:
NSBundle * bundleWithIcon = [NSBundle bundleWithIdentifier:bId]; NSString * iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];
但
bundleWithIcon
为nil
。
bundleWithIdentifier:
要求您已经为具有该标识符的包创建了一个NSBundle实例;它只查找以前创建的实例。因此,您需要在文件系统中找到该bundle并通过pathname实例化它。幸运的是,您似乎已经有了关于此问题的链接。
答案 4 :(得分:0)
没有自定义图标的卷将显示一个操作系统的通用图标,您可以在此处硬编码路径。具有自定义图标的卷将在其文件系统上存储该图标,如果未安装,则查找它完全是您的工作。