¿Cómo puedo obtener el icono de un dispositivo de almacenamiento en Mac OS X?

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

  •  06-09-2019
  •  | 
  •  

Pregunta

He encontrado mis dispositivos que utilizan IOServiceGetMatchingServices y obtuve el diccionario propiedad como esta:

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

A partir de ese diccionario que puedo extraer las informaciones de los iconos:

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

Los dos me dan a este (como ejemplo):

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

He intentado extraer el icono utilizando este método:

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

Pero bundleWithIcon es nil.

¿Es esto el método correcto para obtener el icono?

Creo que tengo que cargar el paquete de alguna manera para poder cargarlo con bundleWithIdentifier, ¿cómo puedo hacer esto?

PS: Hay otra pregunta la que (creo) trata de hacer la misma cosa, pero sólo pide haces, no se si esta es la forma correcta.

¿Fue útil?

Solución 2

Andrew Myrick respondió a una pregunta similar en la lista de correo Darwin-dev:

  

KextManagerCreateURLForBundleIdentifier()   en <IOKit/kext/KextManager.h> puede ser   de uso, aunque creo que sólo funciona   para kexts que están ya sea 1) cargado,   o 2) en / S / L / E /. Aquí está la nieve   Leopardo 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);
     

Tenga en cuenta que antes de Snow Leopard, se   Sólo puede funcionar para kexts en / S / L / E; el   existía API, pero no había   headerdoc describir su comportamiento.

Para mí esto funcionó muy bien en Mac OS X 10.5.

Otros consejos

Se puede usar NSWorkspace.
La imagen inicial es de 32x32, pero tiene representaciones de los otros tamaños y escalará en consecuencia

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

esto puede ayudarle. (O quizá no) ...

en jugar con el comando 'ioreg' me encontré con algo que me recordaba a su pregunta, y así lo voy a publicar:

tratar el siguiente comando:

ioreg -c IOMedia -x

que producirá un gran lío de salida que es como la siguiente:

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

todo esto me lleva a creer (y por lo tanto aquí ciegamente recomienda investigar) que si se recorre la coincidencia árbol del registro io contra 'IOMedia' puede obtener los diccionarios de propiedad que van a contener una entrada introducido "IOMediaIcon", lo que en sí mismo parece ser una colección que le informa de un identificador de paquete y un nombre de archivo de recursos.

no quiere decir que esto es fácil ... pero mira en el FireWire SDK para todo el código de ejemplo, es posible que necesite ... en cualquier caso, es probable que sea "mejor" que los caminos precargadas codificantes duros (que podría desaparecer en futuras versiones del sistema operativo).

| K <

  

Los dos me dan a este (como ejemplo):

     

com.apple.iokit.IOStorageFamily (Bundle identificador)     Internal.icns (archivo de recursos)

     

He intentado extraer el icono utilizando este método:

     

NSBundle * bundleWithIcon = [NSBundle bundleWithIdentifier: Oferta];     NSString * IconPath = [bundleWithIcon pathForResource: FICH_R OfType: nil];

     

Pero bundleWithIcon es nil.

bundleWithIdentifier: requiere que usted tenga ya crea una instancia NSBundle para un paquete con ese identificador; que sólo se ve una instancia creada anteriormente. Por lo tanto, tendrá que encontrar el paquete en el sistema de archivos y instanciarlo por nombre de ruta. Afortunadamente, usted parece tener ya el enlace a la pregunta acerca de eso.

Un volumen sin un icono personalizado va a ser visualizado con uno de los iconos genéricos del sistema operativo que se ha codificado los caminos-a aquí. Un volumen con un icono personalizado va a almacenar ese icono en su sistema de archivos, y si no está montado, la búsqueda se hace por completo su trabajo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top