代码之家  ›  专栏  ›  技术社区  ›  Georg Schölly Crazy Developer

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

  •  3
  • Georg Schölly Crazy Developer  · 技术社区  · 16 年前

    我发现我的设备使用 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 它(我认为)试图问同样的事情,但只要求捆绑,如果这是正确的方式,则不是。

    5 回复  |  直到 15 年前
        1
  •  7
  •   Jesús A. Álvarez    16 年前

    您可以使用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);
    
        2
  •  2
  •   Georg Schölly Crazy Developer    15 年前

    就在最近 Andrew Myrick answered a similar question 在Darwin Dev邮件列表上:

    KextManagerCreateURLForBundleIdentifier() 在里面 <IOKit/kext/KextManager.h> 可能是 有用,尽管我相信它只起作用 对于1)加载的kexts, 或2)in/s/l/e/。这是雪 豹头兽:

    /*!
     * @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);
    

    注意在雪豹之前 仅适用于Kexts in/s/l/e;The API存在,但没有 描述其行为的校长。

    对我来说,这在Mac OS X 10.5上非常有效。

        3
  •  1
  •   kent    16 年前

    这可能对你有帮助。(或者可能没有)

    在玩“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”,它本身似乎是一个集合,通知您包标识符和资源文件名。

    不要说这很容易…但是看看 火线SDK 对于您可能需要的所有示例代码… 无论如何,它可能比硬编码预填充路径“更好”(在将来的OS版本中可能会消失)。

    k & lt;

        4
  •  0
  •   Peter Hosey    16 年前

    这两个给了我(举个例子):

    com.apple.iokit.iostoragefamily(捆绑标识) internal.icns(资源文件)

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

    nsbundle*bundlewithicon=[nsbundle bundlewithIdentifier:bid]; nsstring*iconpath=[bundlewithicon pathforresource:rfile of type:nil];

    但是 bundleWithIcon nil .

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

        5
  •  0
  •   Azeem.Butt    15 年前

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