Как получить значок устройства хранения данных в Mac OS X?

StackOverflow https://stackoverflow.com/questions/580002

  •  06-09-2019
  •  | 
  •  

Вопрос

Я нашел свои устройства с помощью 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, Как я могу это сделать?

ПС: Есть еще вопрос который (я думаю) пытается спросить то же самое, но запрашивает только пакеты, а не правильно ли это.

Это было полезно?

Решение 2

Недавно Эндрю Майрик ответил на аналогичный вопрос в списке рассылки darwin-dev:

KextManagerCreateURLForBundleIdentifier()в <IOKit/kext/KextManager.h> может быть полезен, хотя я считаю, что это работает только для KEXT, которые либо 1) загружены, либо 2) в/с/л/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 в/S/L/E;API существовал, но не было Headerdoc, описывающего его поведение.

Для меня это очень хорошо работало в Mac OS X 10.5.

Другие советы

Вы можете использовать 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);

это может вам помочь.(а может и нет)...

Играя с командой «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

все это заставляет меня поверить (и поэтому я слепо рекомендую вам изучить), что если вы просматриваете дерево реестра io, сопоставляя его с «IOMedia», вы можете получить словари свойств, которые будут содержать запись с ключом «IOMediaIcon», которая сама по себе выглядит как коллекция, информирующая вас об идентификаторе пакета и имени файла ресурсов.

не сказать, что это легко...но загляни в FireWire SDK для всего примера кода, который вам может понадобиться...в любом случае это, вероятно, «лучше», чем предварительно заполненные пути жесткого кодирования (которые могут исчезнуть в будущих выпусках ОС).

|К<

Эти двое дают мне это (в качестве примера):

com.apple.iokit.iostoragefamily (идентификатор пакета) Internal.icns (файл ресурса)

Я попытался извлечь значок, используя этот метод:

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

Но bundleWithIcon является nil.

bundleWithIdentifier: требует, чтобы вы уже создали экземпляр NSBundle для пакета с этим идентификатором;он ищет только ранее созданный экземпляр.Поэтому вам нужно будет найти пакет в файловой системе и создать его экземпляр по пути.К счастью, у вас, кажется, уже есть ссылка на вопрос об этом.

Том без специального значка будет отображаться с одним из общих значков ОС, к которому здесь жестко запрограммированы пути.Том с пользовательским значком будет хранить этот значок в своей файловой системе, и если он не смонтирован, поиск его станет полностью вашей задачей.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top