3

我发现我的设备正在使用IOServiceGetMatchingServices并得到这样的属性字典:

kernResult = IORegistryEntryCreateCFProperties(nextMedia,
                    (CFMutableDictionaryRef *)&props,
                                              kCFAllocatorDefault, 0);

从该字典中,我可以提取图标的信息:

NSString *bId = [props valueForKeyPath:@"IOMediaIcon.CFBundleIdentifier"];
NSString *rFile = [props valueForKeyPath:@"IOMediaIcon.IOBundleResourceFile"];

那两个给了我这个(例如):

com.apple.iokit.IOStorageFamily(捆绑标识符)
Internal.icns(资源文件)

我尝试使用此方法提取图标:

NSBundle *bundleWithIcon = [NSBundle bundleWithIdentifier:bId];
NSString *iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];

但是bundleWithIconnil

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

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

PS:还有另一个问题(我认为)试图问同样的事情,但只要求捆绑,而不是如果这是正确的方法。

4

5 回答 5

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);
于 2009-02-25T09:08:45.483 回答
2

就在最近,Andrew Myrick在 darwin-dev 邮件列表上回答了一个类似的问题:

KextManagerCreateURLForBundleIdentifier() in<IOKit/kext/KextManager.h>可能有用,但我相信它只适用于 1) 已加载或 2) 在 /S/L/E/ 中的 kext。这是雪豹头文件:

/*!
 * @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 中的 kext;API 存在,但没有描述其行为的 headerdoc。

对我来说,这在 Mac OS X 10.5 上运行得非常好。

于 2009-02-24T12:29:05.637 回答
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以获取您可能需要的所有示例代码……无论如何,它可能比硬编码预填充路径“更好”(这可能会在未来的操作系统中消失发布)。

|K<

于 2009-05-12T15:44:45.137 回答
0

那两个给了我这个(例如):

com.apple.iokit.IOStorageFamily(捆绑标识符) Internal.icns(资源文件)

我尝试使用此方法提取图标:

NSBundle *bundleWithIcon = [NSBundle bundleWithIdentifier:bId]; NSString *iconPath = [bundleWithIcon pathForResource:rFile ofType:nil];

但是bundleWithIconnil

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

于 2009-02-24T01:58:12.923 回答
0

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

于 2009-10-14T13:27:45.410 回答