Revertir asociación de tipo de archivo

12

Ocasionalmente trabajo con paquetes de iTunes Music Store. Estos paquetes tienen una .itmspextensión. Al igual que .app, .itmspes esencialmente un directorio contenedor. .itmspLas carpetas contienen XML y archivos multimedia.

La última actualización de Xcode y / o Mac OS X (Xcode 4.6.1 en Mac OS 10.8.3) ha secuestrado la asociación de tipo de archivo para directorios con la .itmspextensión. Anteriormente se trataban como carpetas normales: no es necesario hacer doble clic para ver el interior. Ahora, tengo que hacer doble clic en ellos para interactuar con ellos. Cuando lo hago, un programa llamado Application Loader intenta abrirlos. Para ver el interior, tengo que hacer clic derecho y seleccionar "Mostrar contenido del paquete". Estoy tratando con miles de estos archivos en un momento dado, por lo que eso no funcionará.

Intenté cambiar o eliminar la asociación de tipo de archivo usando Obtener información y RCDefaultApp. Ninguno de los dos funciona. Eliminar la asociación de tipo de archivo simplemente convierte los .itmspdirectorios en archivos en blanco. Al igual que eliminar Application Loader.app por completo. En cualquier caso, todavía no puedo navegar por el contenido sin hacer clic derecho.

La respuesta previamente aceptada funcionó de maravilla por un tiempo: lsregister -u /Applications/Contents/Applications/Application\ Loader.app/dejó de funcionar desde que actualicé Xcode y / o Mac OS X. Si tiene instalado Xcode, debería poder probarlo usted mismo nombrando un directorio foo.itmsp.

¿Cómo puedo hacer que los .itmsparchivos se traten como carpetas una vez más?

michaelmichael
fuente
¿Has intentado arrastrar y soltar un archivo en el ícono de la aplicación Xcode y ver si hace lo que quieres?
MrDaniel
Gracias por la sugerencia. No es relevante para el problema en cuestión, por lo que intentaré editar mi pregunta para aclarar mi intención.
michaelmichael
1
¿Qué versión de OS X estás ejecutando? ¿Qué versión de Xcode?
Old Pro
Eliminé mi respuesta, que eliminó los tipos de CFBundleDocumentTypes y eliminé en Launch Service DataBase. Funciona por un tiempo pero parece reafirmarse nuevamente en algún momento más adelante.
markhunte

Respuestas:

11

El problema: las carpetas .itmsp se muestran como archivos

El Finder trata las carpetas .itmsp como paquetes , es decir, como si fueran un solo archivo. Por ejemplo, en la vista de columna, todo lo contenido en la carpeta .itmsp es invisible, solo se muestra el icono del documento:

ingrese la descripción de la imagen aquí

El Finder considera que un directorio es un paquete si se cumple alguna de las siguientes condiciones (de la Guía de programación de paquetes ):

  1. El directorio tiene una extensión de nombre de archivo conocida: .app, .bundle, .framework, .plugin, .kext, etc. (como se define en /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist. Esta es una lista binaria, ábrala con Xcode:) open -a Xcode Info.plist.

  2. El directorio tiene una extensión que algunas otras reclamaciones de aplicaciones representan un tipo de paquete (busque com.apple.packageen la salida mdls -name kMDItemContentTypeTree <foldername>para averiguarlo).

  3. El directorio tiene su bit de paquete establecido (si GetFileInfo -ab <foldername>devuelve 1, está establecido).

El caso 2. se aplica a las carpetas .itmsp: Application Loader.appexporta el tipo com.apple.itunes-producer.itmspy lo configura para que se ajuste a com.apple.package:

$ mkdir foo.itmsp
$ mdls -name kMDItemContentTypeTree foo.itmsp/
kMDItemContentTypeTree = (
    "com.apple.itunes-producer.itmsp",
    "com.apple.package",
    (...)
)
$ grep -B 5 -A 8 com.apple.package /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Info.plist 
    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>com.apple.package</string>
                <string>public.composite-content</string>
            </array>
            <key>UTTypeDescription</key>
            <string>iTunes Package</string>
            <key>UTTypeIconFile</key>
            <string>ITMSP.icns</string>
            <key>UTTypeIdentifier</key>
            <string>com.apple.itunes-producer.itmsp</string>

Una solución: volver a declarar el tipo com.apple.itunes-producer.itmsp

Una solución sería volver a declarar el tipo com.apple.itunes-producer.itmspy la extensión itmspcomo una carpeta y forzar a Launch Services a usar la declaración de tipo modificada.

Nota IMPORTANTE:

Aunque resuelve de manera confiable el problema del OP, la solución propuesta, cuando se aplica a otros paquetes, no los muestra como carpetas.

Descubrí que la solución propuesta parece funcionar solo con los tipos de archivos declarados por las aplicaciones ubicadas en una ruta de aplicación no estándar.

Este es el caso con Application Loader.app, que se encuentra en /Applications/Xcode.app/Contents/Applications/.

Si está interesado en una solución parcial, marque el final de esta respuesta.

Para que el Finder muestre las carpetas .itmsp como carpetas, siga los siguientes pasos:

  1. Abra Automator en la carpeta Aplicaciones y seleccione Aplicación :

    ingrese la descripción de la imagen aquí

  2. Seleccione Utilidades en la lista Biblioteca, seleccione Ejecutar script de shell y arrástrelo al panel de la derecha:

    ingrese la descripción de la imagen aquí

  3. Reemplace el contenido del script predeterminado con exit 0:

    ingrese la descripción de la imagen aquí

  4. Guarde la aplicación como itmspOpener:

    ingrese la descripción de la imagen aquí

  5. Cierra Automator.

  6. Seleccione itmspOpener.appy muestre sus contenidos:

    ingrese la descripción de la imagen aquí

  7. Localice Contenido> Info.plist y ábralo con su editor favorito:

    ingrese la descripción de la imagen aquí

  8. Reemplace estas secciones en Info.plist:

    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeExtensions</key>
            <array>
                <string>itmsp</string>
            </array>
            <key>CFBundleTypeName</key>
                <string>itmsp folder</string>
            <key>CFBundleTypeRole</key>
                <string>Viewer</string>
            <key>CFBundleTypeIconFile</key>
                <string>folder</string>
            <key>LSTypeIsPackage</key>
                <false/>
            <key>LSHandlerRank</key>
                <string>Owner</string>
        </dict>
    </array>
    (...)
    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>kUTTypeDirectory</string>
            </array>
            <key>UTTypeDescription</key>
            <string>itmsp folder</string>
            <key>UTTypeIconFile</key>
            <string>folder.icns</string>
            <key>UTTypeIdentifier</key>
            <string>com.apple.itunes-producer.itmsp</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <string>itmsp</string>
            </dict>
        </dict>
    </array>
    

    Nota: ¿Por qué en kUTTypeDirectorylugar de public.directoryadentro UTExportedTypeDeclarations? De la documentación de Apple : Importante: cuando use UTI definidas por el sistema en su código, debe usar las constantes definidas UTCoreTypes.hen el marco de Launch Services cuando estén disponibles, en lugar de las cadenas de UTI reales. Por ejemplo, pase kUTTypeApplication en lugar de "com.apple.application". Los "Identificadores de tipo uniforme declarados por el sistema" enumeran estas constantes además de las cadenas UTI.

  9. Asocia un archivo .itmsp itmspOpenery presiona el botón Change All...:

    ingrese la descripción de la imagen aquí

  10. Restablezca la base de datos de Launch Services:

    $ lsregister -kill -r -domain local -domain system -domain user
    

    (en OS X 10.8 lsregisterse encuentra en /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/).

  11. Cree una carpeta .itmsp y enumere sus propiedades:

    $ mkdir foo3.itmsp
    $ mdls -name kMDItemContentTypeTree foo3.itmsp/
    kMDItemContentTypeTree = (
        "public.folder",
        "public.directory",
        "public.item"
    )
    

    Debido a que la base de datos de Launch Services se restableció, ahora el Finder muestra las carpetas .itmsp como carpetas.

  12. Abrir itmspOpener.apppara cargar su archivo plist y registrar com.apple.itunes-producer.itmsp:

    $ open ~/Desktop/itmspOpener.app
    
  13. Inicio Application Loader.app:

    $ open '/Applications/Xcode.app/Contents/Applications/Application Loader.app'
    

    La carpeta foo3.itmspaún debe mostrarse como una carpeta.

  14. Verifique nuevamente las propiedades de la carpeta:

    $ mdls -name kMDItemContentTypeTree foo3.itmsp/
    kMDItemContentTypeTree = (
        "public.directory",
        "public.item",
        "public.content"
    )
    

    com.apple.package no se agregó a los atributos de metadatos de la carpeta, por eso el Finder todavía muestra las carpetas .itmsp como carpetas.

Solución automatizada: mostrar carpetas .itmsp como carpetas después de iniciar sesión

Para mostrar las carpetas .itmsp como carpetas después de iniciar sesión:

  1. Crear itmspOpener.appy modificar su Info.plistcomo se describe anteriormente.

  2. Cree /usr/local/bin/itmspTypeLoadercon este contenido (la variable itmspOpenerapunta a la ubicación donde itmspOpener.appreside, cambie según sea necesario):

    #!/bin/bash
    
    itmspOpener="/Users/jaume/Applications/itmspOpener.app/"
    
    echo "$(date): Starting" > /tmp/itmspTypeLoader.log
    sleep 15
    echo "$(date): Deleting Launch Services database" >> /tmp/itmspTypeLoader.log
    /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user >> /tmp/itmspTypeLoader.log
    sleep 15
    echo "$(date): Starting $itmspOpener" >> /tmp/itmspTypeLoader.log
    open $itmspOpener >> /tmp/itmspTypeLoader.log
    sleep 1
    echo "$(date): Starting Application Loader.app" >> /tmp/itmspTypeLoader.log
    open "/Applications/Xcode.app/Contents/Applications/Application Loader.app/"
    
    # Wait until process "Application Loader.app" exists
    while [ $(ps -ef|grep -v grep|grep -c "Application Loader") -ne 1 ]; do
        sleep 1
        echo "$(date): Waiting" >> /tmp/itmspTypeLoader.log
    done
    # Send TERM signal
    kill -TERM $(ps -ef|grep "Application Loader"|grep -v grep|awk "{print \$2}")
    if [ $? -eq 0 ]; then
        echo "$(date): Application Loader killed" >> /tmp/itmspTypeLoader.log
    else
        echo "$(date): Application Loader could not be killed" >> /tmp/itmspTypeLoader.log
    fi
    echo "$(date): Exiting" >> /tmp/itmspTypeLoader.log
    

    Tanto sleep 15antes como después de correr lsregisterson de suma importancia. Si no ve el resultado deseado, pruebe diferentes demoras.

  3. Crea /usr/local/bin/itmspTypeLoaderLaunchercon este contenido:

    #!/bin/bash
    
    # $1 returns the short name of the user who is logging in
    su - $1 -c /usr/local/bin/itmspTypeLoader &
    
  4. Establecer ambos scripts ejecutables:

    $ sudo chmod a+x /usr/local/bin/itmspTypeLoader /usr/local/bin/itmspTypeLoaderLauncher 
    
  5. Establecer /usr/local/bin/itmspTypeLoaderLaunchercomo enlace de inicio de sesión :

    $ sudo defaults write com.apple.loginwindow LoginHook /usr/local/bin/itmspTypeLoaderLauncher
    
  6. Reinicie para que los cambios surtan efecto. Después de iniciar sesión, debería ver esto:

    ingrese la descripción de la imagen aquí

    y lsregister -dumpdebe revelar que itmspOpener.app's UTExportedTypeDeclarationstiene prioridad sobre Application Loader.app' s:

    $ lsregister -dump | less
    bundle  id:            24748
            path:          /Users/jaume/Desktop/itmspOpener.app/
            name:          itmspOpener
            (...)
            flags:         apple-internal  relative-icon-path  ui-element  has-min-sys-version-by-arch  hi-res-capable  user-can-change-hi-res-mode  
            item flags:    container  package  application  extension-hidden  native-app  scriptable  services  x86_64  
            (...)
            --------------------------------------------------------
            type    id:            33796
                    uti:           com.apple.itunes-producer.itmsp
                    description:   itmsp folder
                    flags:         exported  active  apple-internal  trusted  
                    icon:          Contents/Resources/folder.icns
                    conforms to:   kuttypedirectory
                    tags:          .itmsp
            --------------------------------------------------------
            (...)
    bundle  id:            24600
            path:          /Applications/Xcode.app/Contents/Applications/Application Loader.app/
            name:          Application Loader
            (...)
            flags:         apple-internal  relative-icon-path  hi-res-capable  user-can-change-hi-res-mode  
            item flags:    container  package  application  extension-hidden  native-app  i386  x86_64  
            (...)
            --------------------------------------------------------
            type    id:            33832
                    uti:           com.apple.itunes-producer.itmsp
                    description:   iTunes Package
                    flags:         exported  inactive  apple-internal  trusted  
                    icon:          Contents/Resources/ITMSP.icns
                    conforms to:   com.apple.package, public.composite-content
                    tags:          .itmsp
            --------------------------------------------------------
    

    ¿Ve la inactivebandera establecida en el tipo de exportación de Application Loader.app? Derrotamos a Application Loader.

La prueba de fuego: las carpetas .itmsp aún se muestran como tales después de la actualización de iTunes

Recientemente actualicé Xcode:

ingrese la descripción de la imagen aquí

y puede confirmar que las carpetas .itmsp se mostraron como carpetas durante la actualización:

ingrese la descripción de la imagen aquí

y después:

ingrese la descripción de la imagen aquí

Una solución parcial: el paquete mostrará el contenido cuando se hace doble clic

Como se comentó anteriormente, el procedimiento detallado anteriormente no funcionará con carpetas arbitrarias que el Finder muestra como paquetes.

Sin embargo, si solo desea poder hacer doble clic en un paquete para abrirlo, hay una manera de hacerlo con un bashscript y Automator:

  • El script crea una carpeta temporal oculta dentro del paquete, la revela en el Finder (revelando así el paquete como una carpeta) y luego elimina la carpeta temporal.

    Nota:

    En su lugar, el script podría crear un archivo oculto y temporal. Sin embargo, prefiero crear una carpeta porque rmdirsolo elimina carpetas vacías , mientras que rmelimina cualquier archivo, por lo que si, por alguna razón. el script causa estragos, solo se eliminarán las carpetas vacías, lo que probablemente no sea tan malo como si se eliminaran los archivos.

  • Automator agrupa el script en una aplicación que se asociará con los archivos del paquete.

Estos son los pasos para crear una aplicación de este tipo. Usaré archivos .itmsp como ejemplo de tipo de paquete en la explicación a continuación:

  1. Abra Automator en la carpeta Aplicaciones y seleccione Aplicación :

    ingrese la descripción de la imagen aquí

  2. Seleccione Utilidades en la lista Biblioteca, seleccione Ejecutar script de shell y arrástrelo al panel de la derecha:

    ingrese la descripción de la imagen aquí

  3. Conjunto de entrada Paso a como argumentos :

    ingrese la descripción de la imagen aquí

  4. Reemplace el contenido del script predeterminado con esto:

    for f in "$@"; do
        # If not dealing with a directory, exit
        if [ ! -d "$f" ]; then exit; fi
        # Create a temporary directory inside the itmsp "file"
        tmpdir="$f/.itmspOpener$$"
        if mkdir $tmpdir; then
            # Reveal in Finder
            open -R $tmpdir
            # Delete temporary file
            rmdir $tmpdir
        fi
    done
    
  5. Guarde la aplicación como itmspOpener:

    ingrese la descripción de la imagen aquí

  6. Cierra Automator.

Ahora tiene una aplicación que puede abrir archivos .itmsp como carpetas si está asociada a ella.

Hay un problema cosmético: tal como está, los archivos asociados tendrán el icono de documento blanco estándar:

ingrese la descripción de la imagen aquí

Arreglemos esto también:

  1. Asegúrese de que Automator esté cerrado.

  2. Seleccione itmspOpener y muestre su contenido:

    ingrese la descripción de la imagen aquí

  3. Localice Contenido> Info.plist y ábralo con su editor favorito:

    ingrese la descripción de la imagen aquí

  4. Reemplace el valor de esta clave en la CFBundleDocumentTypesmatriz:

    <key>CFBundleTypeName</key>
    <string>itmsp folder</string>
    

    y agregue esta clave:

    <key>CFBundleTypeIconFile</key>
    <string>folder</string>
    

    Ahora, la sección se ve así:

    ingrese la descripción de la imagen aquí

  5. Cambie al Finder, seleccione una carpeta, presione I, seleccione el icono de carpeta en la esquina superior izquierda y cópielo con C:

    ingrese la descripción de la imagen aquí

  6. Abra Vista previa y seleccione Archivo> Nuevo desde el portapapeles. Guarde el archivo como folder.icns:

    ingrese la descripción de la imagen aquí

  7. Copiar folder.icnsa itmspOpener/Contents/Resources:

    ingrese la descripción de la imagen aquí

  8. Asocia un archivo .itmsp itmspOpenery presiona el botón Change All...:

    ingrese la descripción de la imagen aquí

El ícono de los archivos .itmsp debería cambiar a una carpeta, o al menos eso pensé: desafortunadamente, este no fue el caso. Así que moví la aplicación itmspOpener a otra ubicación (creé una carpeta temporal en mi escritorio, la moví allí y de regreso a mi escritorio). Eso actualizó la información del icono en el Finder:

ingrese la descripción de la imagen aquí

Ahora haga doble clic en un archivo .itmsp y vea cómo se abre como una carpeta:

ingrese la descripción de la imagen aquí

jaume
fuente
Esto es muy impresionante ... PERO parece tener un problema molesto: si el Finder está en vista de columna (mi tipo de vista preferido), todo lo contenido en la .itmspcarpeta es invisible. No puedo entender por qué, pero ahí está. Además, si tuviera mis druthers, no tendrías que hacer doble clic en el archivo para ver el interior, pero bueno.
michaelmichael
1
Tienes razón. No anticipé que usó la vista de columna, aunque debo decir que tiene mucho sentido cuando se trata de miles de carpetas .itmsp. Pero encontré una manera de resolver el problema, es decir, forzar al Finder a tratar las carpetas .itmsp como carpetas. Echa un vistazo a mi edición (o salta directamente al último párrafo llamado La solución, pero no te olvides de modificar itmspOpener's Info.plist primero como se describe en el párrafo El truco.)
jaume
¡Increíble! Gracias por la respuesta. Este es un aspecto muy interesante de algunas de las cosas que hacen que el Finder y OS X funcionen.
michaelmichael
Gracias, me alegro de que te haya resultado útil. (Editaré la respuesta más tarde para mejorar la lectura y darle más estructura.)
jaume
Finalmente encontré algo de tiempo para editar la respuesta. Reordené párrafos y agregué evidencia de que la solución explicada en mi respuesta es inmune a las actualizaciones de iTunes.
jaume
7

Una opción sería anular el registro del Application Loader lsregister -u /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/, pero se vuelve a registrar si se abre, si se reconstruye la base de datos de Launch Services, o posiblemente si se actualiza Xcode.

También puede comentar las entradas en los diccionarios CFBundleDocumentTypes y UTExportedTypeDeclarations en /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Info.plisty ejecutar lsregister -f /Applications/Xcode.app/Contents/Applications/Utilities/Application\ Loader.app/. No invalida la firma del código de Xcode, pero las actualizaciones podrían sobrescribir los cambios.

El camino completo a lsregister está /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregisteren 10.5 y posterior.

Lri
fuente
¿Está seguro de que anular el registro de la aplicación después de cambiarla Info.plistanulará el registro de los tipos de archivos que eliminó de la lista? Puedo imaginarlo funcionando y puedo imaginarlo fácilmente fallando. también.
Old Pro
@OldPro Sí, lsregister -u $app && lsregister $appparece aplicar los cambios a un Info.plist al menos en este caso.
Lri
Esta es una respuesta fabulosa: tenga en cuenta que la próxima vez que actualice Xcode, puede terminar con un cargador de aplicaciones que registra el valor predeterminado, CFBundleDocumentTypespor lo que puede eliminar esa "herramienta" cuando aparezca si no la necesita y / o cansado de modificarlo.
bmike
2

Aquí hay un extracto relevante de la documentación de Apple sobre paquetes ( énfasis agregado )

Cómo identifica el sistema los paquetes y paquetes

El Finder considera que un directorio es un paquete si se cumple alguna de las siguientes condiciones:

  • El directorio tiene una extensión de nombre de archivo conocida: .app, .bundle, .framework, .plugin, .kext, etc.
  • El directorio tiene una extensión que algunas otras reclamaciones de aplicaciones representan un tipo de paquete; ver " Paquetes de documentos ".
  • El directorio tiene su conjunto de bits de paquete.

La forma preferida de especificar un paquete es darle al directorio del paquete una extensión de nombre de archivo conocida. En su mayor parte, Xcode se encarga de esto al proporcionar plantillas que aplican la extensión correcta. Todo lo que tiene que hacer es crear un proyecto Xcode del tipo apropiado.

Es casi seguro que Xcode representa que afirma que .itmsprepresenta un tipo de paquete, como se describe en Paquetes de documentos . Entonces, quizás eliminar esa extensión de Xcode Info.plistsea ​​suficiente, pero sospecho que una vez que el Finder haya notado esa asociación, eliminarla de Xcode no la deshacerá. ¿Cuáles son las "aplicaciones recomendadas" que obtienes cuando haces clic derecho en "Abrir con ..."? Debe verificar todas sus listas de información.

Sugiero ver si puede salirse con la suya lsregister -upara anular el registro de cualquier aplicación que reclame .itmsp. De lo contrario, es posible que tenga que quitar .itmspde todas las plists y luego matar a toda la base de datos usando el buscador asociación lsregister -kill -seed. Nunca lo hizo, sin saber cuánto daño le hará al resto de su sistema. Probablemente desee anular el registro, luego editar las listas, luego eliminar y volver a colocar la base de datos. No me sorprendería si anular el registro no elimina la asociación si ya la eliminó de la lista, y reseed la agregará nuevamente si aún no la ha eliminado. Además, de esta manera no perderá todas las otras asociaciones por las aplicaciones ofensivas.

Lo que es peor, Xcode podría haber pasado y establecer el bit de paquete en todas las carpetas. Supongo que tendrías que escribir un script usando GetFileInfoy SetFilepara escanear el disco y deshacerlos, lo cual es un poco complicado, pero factible. Los dedos que cruzan los bultos permanecen sin ajustar. Use GetFileInfopara verificar probando algunos.

Viejo pro
fuente
0

Creo que puedes arreglar esto usando

/usr/bin/SetFile -a B /path/to/file.itmsp

Pruébelo en uno antes de probarlo en todos los demás, obviamente.

Si necesita que se ejecute en todos ellos en una carpeta determinada:

find . -name \*.itmsp -exec /usr/bin/SetFile -a B {} \;

debería hacerlo por ti.

TJ Luoma
fuente
1
SetFile -a B establece el bit de paquete. De hecho, debería ser desactivado: SetFile -a b. Pero esto no tendrá efecto ya que el Has bundlebit no está establecido: GetFileInfo -ab foo.itmspretornos 0.
jaume