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

发布于 2024-07-13 21:49:40 字数 1116 浏览 4 评论 0原文

我使用 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:还有另一个问题(我认为)试图问同样的事情,但只是问对于捆绑包,如果这是正确的方法则不是。

I've found my devices using IOServiceGetMatchingServices and got the property dictionary like this:

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

From that dictionary I can extract the informations for the icons:

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

Those two give me this (as an example):

com.apple.iokit.IOStorageFamily   (Bundle identifier)
Internal.icns                     (Resource File)

I tried to extract the icon using this method:

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

But bundleWithIcon is nil.

Is this even the correct method to get the icon?

I think I have to somehow load the bundle to be able to load it with bundleWithIdentifier, how can I do this?

PS: There's another question which (I think) tries to ask the same thing, but only asks for bundles, not if this is the correct way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

゛时过境迁 2024-07-20 21:49:40

您可以使用 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);

You could use NSWorkspace.
The initial image is 32x32, but it has representations for the other sizes and will scale accordingly

NSWorkspace * ws = [NSWorkspace sharedWorkspace];
NSImage * icon = [ws iconForFile:@"/Volumes/Whatever"];
NSLog(@"%@", [icon representations]); // see what sizes the icon has
icon.size = NSMakeSize(512, 512);
就像说晚安 2024-07-20 21:49:40

就在最近Andrew Myrick 回答了类似的问题达尔文开发邮件列表:

KextManagerCreateURLForBundleIdentifier()
中可能是
有用,虽然我相信它只有效
对于 1) 加载的 kext,
或 2) 在 /S/L/E/ 中。 这里是雪
Leopard 标头文档:

<前><代码>/*!
* @function KextManagerCreateURLForBundleIdentifier
* @abstract 创建一个 URL,定位具有给定包标识符的 kext。
*
* @参数分配器
* 用于为新对象分配内存的分配器。
* 传递NULL; 或kCFAllocatorDefault
* 使用当前默认分配器。
* @参数 kextIdentifier
* 要查找的包标识符。
*
* @结果
* CFURLRef 定位具有请求的包标识符的 kext。
* 返回NULL; 如果找不到 kext,或者出现错误。
*
* @讨论
* 首先根据是否加载来查找 Kext,然后根据版本来查找。
*具体来说,如果kextIdentifier 识别一个 kext
* 当前已加载,
* 如果该 kext 仍然存在于磁盘上,则返回的 URL 将找到该 kext。
* 如果请求的kext没有加载,
* 或者如果它的包不在最初加载的位置,
* 返回的 URL 将找到所需 kext 的最新版本,
* 如果可以在系统扩展文件夹中找到它。
* 如果找不到 kext 版本,则 NULL 被返回。
*/
CFURLRef KextManagerCreateURLForBundleIdentifier(
CFAllocatorRef 分配器,
CFStringRef kextIdentifier);

请注意,在 Snow Leopard 之前,它
可能仅适用于 /S/L/E 中的 kext; 这
API存在,但没有
headerdoc 描述其行为。

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

Just recently Andrew Myrick answered a similar question on the darwin-dev mailing list:

KextManagerCreateURLForBundleIdentifier()
in <IOKit/kext/KextManager.h> may be
of use, though I believe it only works
for kexts that are either 1) loaded,
or 2) in /S/L/E/. Here is the Snow
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);

Note that prior to Snow Leopard, it
may only work for kexts in /S/L/E; the
API existed, but there was no
headerdoc describing its behavior.

For me this worked really well on Mac OS X 10.5.

德意的啸 2024-07-20 21:49:40

这可能对你有帮助。 (或者也许不是)......

在使用“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<

this may help you. (or maybe not)...

in playing around with the 'ioreg' command i came across something that reminded me of your question, and so I'll post it:

try issuing the following command:

ioreg -c IOMedia -x

which will yield a big mess of output which looks something like this:

  |     +-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

this all leads me to believe (and thus here blindly recommend that you investigate) that if you traverse the io registry tree matching against 'IOMedia' you can get property dictionaries that will contain an entry keyed "IOMediaIcon," which itself appears to be a collection informing you of a bundle identifier and a resource file name.

not to say that this is easy... but look into the FireWire SDK for all the example code you may need...
in any case it's probably "better" than hard-coding pre-filled paths (which might disappear in future OS releases).

|K<

软糖 2024-07-20 21:49:40

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

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

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

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

但是bundleWithIconnil

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

Those two give me this (as an example):

com.apple.iokit.IOStorageFamily (Bundle identifier)
Internal.icns (Resource File)

I tried to extract the icon using this method:

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

But bundleWithIcon is nil.

bundleWithIdentifier: requires you to have already created an NSBundle instance for a bundle with that identifier; it only looks up a previously-created instance. Therefore, you'll need to find the bundle in the file-system and instantiate it by pathname. Fortunately, you seem to already have the link to the question about that.

烟若柳尘 2024-07-20 21:49:40

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

A volume without a custom icon is going to be displayed with one of the OS's generic icons which you've hard-coded paths to here. A volume with a custom icon is going to store that icon on its filesystem, and if it's not mounted, finding it becomes entirely your job.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文