如何在Mac OS X中获取存储设备的图标?

时间:2009-02-24 00:29:44

标签: cocoa iokit

我发现我的设备使用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];

bundleWithIconnil

这是获取图标的正确方法吗?

我想我必须以某种方式加载捆绑包以便能够使用bundleWithIdentifier加载它,我该怎么做?

PS:There's another question(我认为)试图问同样的事情,但只要求捆绑,而不是这是正确的方式。

5 个答案:

答案 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];

     

bundleWithIconnil

bundleWithIdentifier:要求您已经为具有该标识符的包创建了一个NSBundle实例;它只查找以前创建的实例。因此,您需要在文件系统中找到该bundle并通过pathname实例化它。幸运的是,您似乎已经有了关于此问题的链接。

答案 4 :(得分:0)

没有自定义图标的卷将显示一个操作系统的通用图标,您可以在此处硬编码路径。具有自定义图标的卷将在其文件系统上存储该图标,如果未安装,则查找它完全是您的工作。