2009-02-24 107 views
3

我发现使用IOServiceGetMatchingServices我的设备,并获得属性字典是这样的:如何在Mac OS X中获取存储设备的图标?

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哪(我认为)试图要求同样的事情,但只要求捆绑,而不是如果这是正确的方式。

回答

2

就在最近的达尔文-dev邮件列表上Andrew Myrick answered a similar question

KextManagerCreateURLForBundleIdentifier()<IOKit/kext/KextManager.h>可能是使用的 ,但我相信它仅适用 项目,是指1)加载 kext文件,或2 )in/S/L/E /。这里是雪 豹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); 

注意,之前雪豹,它 可以仅对于在/ S/L/E kext文件工作; API已存在,但没有描述其行为的headerdoc。

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

0

这两个给我这个(作为一个例子):

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

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

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

但是bundleWithIconnil

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

+0

麻烦的是,要查看每个包需要2秒钟。难道不应该让IOKit加载该包,以便有一个我可以访问的实例? – 2009-02-24 08:47:18

+0

您可以简单地在/ S/L/E中实例化所有kext捆绑包,也许在应用完成启动后的几秒钟后台。在你完成之后,只要从I/O Kit获得的包标识符是kext的包标识符,bundleWithIdentifier就可以工作。 – 2009-02-24 18:52:37

+0

启动应用程序需要很长时间,应用程序必须在开始时显示图标。 – 2009-02-25 09:56:35

7

您可以使用NSWorkspace。
最初的图像是32×32,但它对于其他尺寸的表示,并相应

NSWorkspace * ws = [NSWorkspace sharedWorkspace]; 
NSImage * icon = [ws iconForFile:@"/Volumes/Whatever"]; 
NSLog(@"%@", [icon representations]); // see what sizes the icon has 
icon.size = NSMakeSize(512, 512); 
+0

这只适用于装入的卷,我也需要装入未装入的装置。 – 2009-02-25 09:19:10

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 

这一切使我相信(并因此在此盲目地建议你投资igate)如果遍历与'IOMedia'匹配的io注册表树,则可以获取将包含键入为“IOMediaIcon”的项的属性字典,该项本身似乎是一个集合,通知您捆绑标识符和资源文件名。

不是说这很容易......但看看到火线SDK所有的示例代码,你可能需要... 在任何情况下,它比硬编码预填充路径可能是“更好” (这可能会在未来的操作系统版本中消失)。

| K <

0

没有自定义图标的卷是要与操作系统的您已经硬编码路径来这里一般一个图标来显示。一个带有自定义图标的卷会将该图标存储在其文件系统中,如果没有安装,找到它就完全成为您的工作。

相关问题