2008-10-13 19 views
6

Deseo crear un paquete a partir de un identificador de paquete arbitrario
p. com.apple.iokit.IOStorageFamilyBuscar paquetes por identificador

No es una cosa razonable a hacer como identificadores de paquete se supone
que ser único, sin embargo el código obvia no funciona:

NSString* bID = @"com.apple.iokit.IOStorageFamily"; 
NSBundle* bundle = [NSBundle bundleWithIdentifier:bID]; 

Este código sólo funciona para los paquetes que ya hemos cargado
(problema del huevo, la gallina y el huevo), y de hecho, tiene
para saber un poco más de lo que desea sobre el identificador
antes de poder hacer cualquier cosa. Para el estilo anterior de ID
Limpio el componente final y lo transformo en
/System/Library/Extensions/IOStorageFamily.kext
que luego carga por ruta.

¿Es este el estado de la técnica o hay una forma más general?

+0

Llego casi un año tarde para responder. ¿Todavía fue útil? –

+0

Es bueno saberlo. El código anterior funciona, pero agregaré KextManagerCreateURLForBundleIdentifier en algún comentario de algún lugar. Gracias. –

Respuesta

3

Recientemente Andrew Myrick answered a similar question en la lista de correo Darwin-dev:

KextManagerCreateURLForBundleIdentifier() en <IOKit/kext/KextManager.h> puede haber de uso, aunque creo que sólo funciona para kexts que están ya sea 1) cargar, 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, que solamente puede funcionar para kexts en/S/L/E; la API existía, pero no había encabezado que describía su comportamiento.

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

+0

Estoy tratando de ubicar el paquete con la misma ID exacta que el póster original, y este código siempre devuelve NULL para mí, pero esto se debe a Sandboxing. Lástima que ya no se puede usar para aplicaciones en la App Store. –

9

Utilice esta

NSString *path = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"com.apple.TextEdit"]; 
+0

¡No del todo! Eso es solo para aplicaciones, mi ejemplo fue un kext. –

0

Si lo que estás buscando es definitivamente un kext, entonces usted podría mirar en el diccionario de información para cada paquete en el directorio// carpeta/S L/Es hasta que encuentre el suyo . No hay búsqueda de paquete por identificador aparte de para Aplicaciones (donde LaunchServices lo hará), y paquetes cargados como ya ha encontrado.

+0

Hasta ahora todos han sido kexts, pero eso podría ser pura casualidad. Digamos que son sin embargo, ¿hay algo terriblemente mal en hackear el camino desde el bundleID o debería realmente iterar los diccionarios de información? Ejército de reserva. –

+0

Siempre está instalado el "qué pasa si" un KEXT que no coincide con ese esquema. Por supuesto, realmente no necesita iterar _every_time, podría crear un esquema de búsqueda y usar eso (mantenerlo actualizado ...). –

4

No creo que Mac OS X mantenga una base de datos global de todos los ID de paquete en todas partes.

Como se señaló, puede encontrar una aplicación de una manera bastante sencilla con NSWorkspace.

Además, como usaste un kext para tu ejemplo, en Leopard (10.5) hay una herramienta llamada "kextfind" que puedes ejecutar para buscar kexts en el sistema Carpeta de extensiones (no se encontrarán kexts en otros lugares) a menos que señale la herramienta en esos otros lugares). kextfind tiene un montón de opciones - véase la página del manual para más detalles - pero para encontrar un kext por ID de paquete se puede hacer esto:

kextfind -bundle-id com.apple.iokit.IOStorageFamily 

estos momentos, no tenemos una API de nivel C para buscar kexts por ID del paquete.

En cuanto a hackear la ruta desde el último componente de la ID del paquete: no lo haga. No hay nada que requiera que el nombre de la envoltura coincida con el último componente de la ID del paquete, y he visto kexts (para no hablar de otros paquetes), donde los dos no coinciden.

0

Para responder a esta pregunta, creo que uno realmente necesita saber "¿Por qué está buscando identificadores de paquetes de esta manera?" Si siempre hay kexts puedes buscar en algunos lugares bastante razonables, si son aplicaciones puedes usar LS, no veo un caso en el cual quieras hacer ambas cosas, así que no veo la necesidad de tener un forma común de hacerlo

Debe tenerse en cuenta que puede tener varias instancias de identificadores de paquetes idénticos en un Volumen.

0

Para completar, debo mencionar que puede buscar todos los paquetes (no solo KEXT) con un identificador de paquete dado usando la clave Spotlight/metadatos kMDItemCFBundleIdentifier; por supuesto, debes estar preparado para manejar el hecho de que haya más de uno (normalmente deberían tener versiones diferentes).

Cuestiones relacionadas