Reverter associação de tipo de arquivo

12

Ocasionalmente, trabalho com pacotes da iTunes Music Store. Esses pacotes têm uma .itmspextensão. Como .app, .itmspé essencialmente um diretório de contêiner. .itmsppastas contêm arquivos XML e de mídia.

A atualização mais recente do Xcode e / ou Mac OS X (Xcode 4.6.1 no Mac OS 10.8.3) seqüestrou a associação de tipo de arquivo para diretórios com a .itmspextensão. Anteriormente, eles eram tratados como pastas normais - não é necessário clicar duas vezes para ver o interior. Agora, eu tenho que clicar duas vezes neles para interagir com eles. Quando o faço, um programa chamado Application Loader tenta abri-los. Para ver dentro, tenho que clicar com o botão direito do mouse e selecionar "Mostrar conteúdo do pacote". Estou lidando com milhares desses arquivos a qualquer momento, para que não funcionem.

Tentei alterar ou remover a associação de tipo de arquivo usando Get Info e RCDefaultApp. Nem funciona. A remoção da associação do tipo de arquivo simplesmente transforma os .itmspdiretórios em arquivos em branco. O mesmo acontece com a exclusão completa do Application Loader.app. Nos dois casos, ainda não consigo navegar pelo conteúdo sem clicar com o botão direito.

A resposta anteriormente aceita funcionou por um tempo: lsregister -u /Applications/Contents/Applications/Application\ Loader.app/parou de funcionar desde que atualizei o Xcode e / ou o Mac OS X. Se você tiver o Xcode instalado, poderá testá-lo nomeando um diretório foo.itmsp.

Como posso fazer com que os .itmsparquivos sejam tratados como pastas mais uma vez?

michaelmichael
fonte
Você já tentou arrastar e soltar um arquivo no ícone do Xcode App e ver se ele faz o que você deseja?
MrDaniel
Obrigado pela sugestão. Não é relevante para o problema em questão, então tentarei editar minha pergunta para esclarecer minha intenção.
22612 Michael michaelmichael
1
Qual versão do OS X você está executando? Qual versão do Xcode?
Old Pro
Excluí minha resposta, que removeu os tipos do CFBundleDocumentTypes e matou no DataBase do serviço de inicialização. Funciona por um tempo, mas parece se reafirmar novamente em algum momento mais tarde.
markhunte

Respostas:

11

O problema: as pastas .itmsp são mostradas como arquivos

O Finder trata as pastas .itmsp como pacotes , ou seja, como se fossem um único arquivo. Por exemplo, no modo de exibição de coluna, qualquer coisa contida na pasta .itmsp é invisível, apenas o ícone do documento é mostrado:

insira a descrição da imagem aqui

O Finder considera um diretório como um pacote se alguma das seguintes condições for verdadeira (no Guia de programação de pacotes ):

  1. O diretório possui uma extensão de nome de arquivo conhecida: .app, .bundle, .framework, .plugin, .kext e assim por diante (conforme definido em /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist. Este é um argumento binário, abra-o com o Xcode:) open -a Xcode Info.plist.

  2. O diretório tem uma extensão que outras reivindicações de aplicativos representam um tipo de pacote (procure com.apple.packagena saída de mdls -name kMDItemContentTypeTree <foldername>para descobrir).

  3. O diretório tem seu bit de pacote definido (se GetFileInfo -ab <foldername>retornar 1, está definido).

O caso 2. se aplica às pastas .itmsp: Application Loader.appexporta o tipo com.apple.itunes-producer.itmspe o configura para 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>

Uma solução: declarar novamente o tipo com.apple.itunes-producer.itmsp

Uma solução seria declarar novamente o tipo com.apple.itunes-producer.itmspe a extensão itmspcomo uma pasta e forçar o Launch Services a usar a declaração de tipo modificada.

Nota importante:

Embora resolva o problema do OP de maneira confiável, a solução proposta, quando aplicada a outros pacotes, não os exibe como pastas.

Descobri que a solução proposta parece funcionar apenas com tipos de arquivos declarados por aplicativos localizados em um caminho de aplicativo não padrão.

É o caso de Application Loader.app, localizado em /Applications/Xcode.app/Contents/Applications/.

Se você estiver interessado em uma solução parcial, verifique o final desta resposta.

Para que as pastas .itmsp sejam exibidas como pastas pelo Finder, siga as próximas etapas:

  1. Abra o Automator na pasta Aplicativos e selecione Aplicativo :

    insira a descrição da imagem aqui

  2. Selecione Utilitários na lista Biblioteca, selecione Executar Shell Script e arraste-o para o painel à direita:

    insira a descrição da imagem aqui

  3. Substitua o conteúdo padrão do script por exit 0:

    insira a descrição da imagem aqui

  4. Salve o aplicativo como itmspOpener:

    insira a descrição da imagem aqui

  5. Feche o Automator.

  6. Selecione itmspOpener.appe mostre seu conteúdo:

    insira a descrição da imagem aqui

  7. Localize Conteúdo> Info.plist e abra-o com seu editor favorito:

    insira a descrição da imagem aqui

  8. Substitua estas seções em 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 que kUTTypeDirectory, em vez de public.directorynos UTExportedTypeDeclarations? Na documentação da Apple : Importante: Ao usar UTIs definidas pelo sistema em seu código, você deve usar as constantes definidas UTCoreTypes.hna estrutura do Launch Services quando disponíveis, em vez das cadeias de caracteres reais da UTI. Por exemplo, passe kUTTypeApplication em vez de "com.apple.application". “Identificadores de tipo uniforme declarados pelo sistema” lista essas constantes além das seqüências de caracteres da UTI.

  9. Associe um arquivo .itmsp ae itmspOpenerpressione o botão Change All...:

    insira a descrição da imagem aqui

  10. Redefina o banco de dados do Launch Services:

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

    (no OS X 10.8 lsregisterestá localizado em /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/.)

  11. Crie uma pasta .itmsp e liste suas propriedades:

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

    Como o banco de dados dos Serviços de Inicialização foi redefinido, agora o Finder mostra pastas .itmsp como pastas.

  12. Abra itmspOpener.apppara carregar seu arquivo plist e registre com.apple.itunes-producer.itmsp- se :

    $ open ~/Desktop/itmspOpener.app
    
  13. Início Application Loader.app:

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

    A pasta foo3.itmspainda deve ser exibida como uma pasta.

  14. Verifique as propriedades da pasta novamente:

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

    com.apple.package não foi adicionado aos atributos de metadados da pasta, é por isso que o Finder ainda exibe pastas .itmsp como pastas!

Solução automatizada: exibindo pastas .itmsp como pastas após o login

Para exibir pastas .itmsp como pastas após o login:

  1. Crie itmspOpener.appe modifique-o Info.plistconforme descrito acima.

  2. Crie /usr/local/bin/itmspTypeLoadercom este conteúdo (a variável itmspOpeneraponta para o local em que itmspOpener.appreside, altere conforme necessário):

    #!/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
    

    Ambos sleep 15antes e depois de correr lsregistersão de extrema importância. Se você não encontrar o resultado desejado, tente atrasos diferentes.

  3. Crie /usr/local/bin/itmspTypeLoaderLaunchercom este conteúdo:

    #!/bin/bash
    
    # $1 returns the short name of the user who is logging in
    su - $1 -c /usr/local/bin/itmspTypeLoader &
    
  4. Defina os dois scripts executáveis:

    $ sudo chmod a+x /usr/local/bin/itmspTypeLoader /usr/local/bin/itmspTypeLoaderLauncher 
    
  5. Defina /usr/local/bin/itmspTypeLoaderLaunchercomo gancho de login :

    $ sudo defaults write com.apple.loginwindow LoginHook /usr/local/bin/itmspTypeLoaderLauncher
    
  6. Reinicie para que as alterações entrem em vigor. Após o login, você deverá ver o seguinte:

    insira a descrição da imagem aqui

    e lsregister -dumpdeve revelar que itmspOpener.appé UTExportedTypeDeclarationstem precedência 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
            --------------------------------------------------------
    

    Você vê o inactivesinalizador definido na exportação de tipo do Application Loader.app? Derrotamos o Application Loader.

As pastas acid test: .itmsp ainda são exibidas como tal após a atualização do iTunes

Atualizei recentemente o Xcode:

insira a descrição da imagem aqui

e pode confirmar que as pastas .itmsp foram mostradas como pastas durante a atualização:

insira a descrição da imagem aqui

e depois:

insira a descrição da imagem aqui

Uma solução parcial: o pacote mostrará o conteúdo ao clicar duas vezes

Como comentado anteriormente, o procedimento detalhado acima não funcionará com pastas arbitrárias que são exibidas como pacotes pelo Finder.

No entanto, se você quiser apenas clicar duas vezes em um pacote para abri-lo, existe uma maneira de fazê-lo com um bashscript e o Automator:

  • O script cria uma pasta temporária oculta dentro do pacote, a revela no Finder (revelando o pacote como uma pasta) e exclui a pasta temporária.

    Nota:

    O script poderia criar um arquivo temporário oculto. No entanto, prefiro criar uma pasta porque rmdirapenas exclui pastas vazias , enquanto rmexclui qualquer arquivo, por isso, por algum motivo. o script causa estragos, apenas pastas vazias serão excluídas, o que provavelmente não é tão ruim quanto se os arquivos fossem excluídos.

  • O Automator agrupa o script em um aplicativo que será associado aos arquivos do pacote.

Estas são as etapas para criar um aplicativo. Usarei arquivos .itmsp como exemplo de tipo de pacote na explicação abaixo:

  1. Abra o Automator na pasta Aplicativos e selecione Aplicativo :

    insira a descrição da imagem aqui

  2. Selecione Utilitários na lista Biblioteca, selecione Executar Shell Script e arraste-o para o painel à direita:

    insira a descrição da imagem aqui

  3. Conjunto de entrada da passagem de como argumentos :

    insira a descrição da imagem aqui

  4. Substitua o conteúdo do script padrão por este:

    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. Salve o aplicativo como itmspOpener:

    insira a descrição da imagem aqui

  6. Feche o Automator.

Agora você tem um aplicativo que pode abrir arquivos .itmsp como pastas, se associado a ele.

Há um problema estético: como está, os arquivos associados terão o ícone padrão de documento branco:

insira a descrição da imagem aqui

Vamos corrigir isso também:

  1. Verifique se o Automator está fechado.

  2. Selecione itmspOpener e mostre seu conteúdo:

    insira a descrição da imagem aqui

  3. Localize Conteúdo> Info.plist e abra-o com seu editor favorito:

    insira a descrição da imagem aqui

  4. Substitua o valor para esta chave na CFBundleDocumentTypesmatriz:

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

    e adicione esta chave:

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

    Agora, a seção fica assim:

    insira a descrição da imagem aqui

  5. Alterne para o Finder, selecione uma pasta, pressione I, selecione o ícone da pasta no canto superior esquerdo e copie-o com C:

    insira a descrição da imagem aqui

  6. Abra Visualizar e selecione Arquivo> Novo na área de transferência. Salve o arquivo como folder.icns:

    insira a descrição da imagem aqui

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

    insira a descrição da imagem aqui

  8. Associe um arquivo .itmsp ae itmspOpenerpressione o botão Change All...:

    insira a descrição da imagem aqui

O ícone dos arquivos .itmsp deve mudar para uma pasta, ou pelo menos pensei: infelizmente, esse não foi o caso. Então, mudei o aplicativo itmspOpener para outro local (criei uma pasta temporária na minha área de trabalho, mudei para lá e voltei para a minha área de trabalho). Isso atualizou as informações do ícone no Finder:

insira a descrição da imagem aqui

Agora clique duas vezes em um arquivo .itmsp e observe-o como uma pasta:

insira a descrição da imagem aqui

jaume
fonte
Isso é muito impressionante ... MAS parece ter um problema: se o Finder estiver na exibição de colunas (meu tipo de exibição preferido), qualquer coisa contida na .itmsppasta ficará invisível. Não sei por que, mas aí está. Além disso, se eu tivesse meus leitores, você não precisaria clicar duas vezes no arquivo para ver dentro, mas tudo bem.
michaelmichael
1
Você está certo. Eu não esperava que você usasse o modo de exibição de coluna, embora deva dizer que faz todo sentido ao lidar com milhares de pastas .itmsp. Mas encontrei uma maneira de resolver o problema, ou seja, forçar o Finder a tratar as pastas .itmsp como pastas. Dê uma olhada na minha edição (ou saltar directamente para o último parágrafo chamado A solução, mas não se esqueça de modificar Info.plist de itmspOpener primeiro como descrito no parágrafo O truque.)
jaume
Inacreditável! Obrigado pela resposta. Esta é uma visão muito interessante de algumas das coisas que fazem o Finder e o OS X funcionarem.
michaelmichael
Obrigado, estou feliz que você tenha achado útil! (Vou editar a resposta mais tarde para melhorar a legibilidade e dar-lhe mais estrutura.)
jaume
Finalmente encontrei algum tempo para editar a resposta. Reordenei parágrafos e acrescentei evidências de que a solução explicada na minha resposta é imune às atualizações do iTunes.
jaume
7

Uma opção seria cancelar o registro do Application Loader lsregister -u /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/, mas ele será registrado novamente se for aberto, se o banco de dados do Launch Services for reconstruído ou, possivelmente, se o Xcode for atualizado.

Você também pode comentar as entradas nos dicionários CFBundleDocumentTypes e UTExportedTypeDeclarations /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Info.pliste executar lsregister -f /Applications/Xcode.app/Contents/Applications/Utilities/Application\ Loader.app/. Não invalida a assinatura de código do Xcode, mas as alterações podem ser substituídas por atualizações.

O caminho completo para o lsregister é /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregisterna versão 10.5 e posterior.

Lri
fonte
Tem certeza de que o cancelamento do registro do aplicativo após a alteração dele Info.plistcancelará o registro dos tipos de arquivos removidos da lista? Eu posso imaginá-lo funcionando e facilmente imaginá-lo falhando. também.
Old Pro
@ OldPro Sim, lsregister -u $app && lsregister $appparece aplicar as alterações em um Info.plist pelo menos nesse caso.
Lri
Esta é uma resposta fabulosa - lembre-se de que na próxima vez que você atualizar o Xcode - você poderá acabar com um Application Loader que registra o padrão. CFBundleDocumentTypesAssim, você pode excluir essa "ferramenta" quando ela aparecer, se não precisar e / ou cansa de modificá-lo.
bmike
2

Aqui está um trecho relevante a partir da Apple documenation sobre pacotes ( grifo nosso )

Como o sistema identifica bundles e pacotes

O Finder considera um diretório como um pacote se alguma das seguintes condições for verdadeira:

  • O diretório possui uma extensão de nome de arquivo conhecida: .app, .bundle, .framework, .plugin, .kext e assim por diante.
  • O diretório possui uma extensão que outras reivindicações de aplicativos representam um tipo de pacote; consulte " Pacotes de documentos ".
  • O diretório tem seu pacote de bits definido.

A maneira preferida de especificar um pacote é fornecer ao diretório do pacote uma extensão de nome de arquivo conhecida. Na maioria das vezes, o Xcode cuida disso para você , fornecendo modelos que aplicam a extensão correta. Tudo que você precisa fazer é criar um projeto Xcode do tipo apropriado.

Quase certamente o Xcode está representando que afirma .itmsprepresentar um tipo de pacote, conforme descrito em Pacotes de Documentos . Portanto, talvez a remoção dessa extensão do Xcode Info.plistfuncione, mas suspeito que, uma vez que a associação tenha sido notada pelo Finder, removê-la do Xcode não a desfará. Quais são os "aplicativos recomendados" que você obtém ao clicar com o botão direito do mouse em "Abrir com ..."? Você precisa verificar todas as listas de informações.

Sugiro ver se você pode se safar com o uso lsregister -upara cancelar o registro de aplicativos que reivindicaram .itmsp. Caso contrário, talvez você precise remover .itmspde todas as listas e depois matar o banco de dados inteiro da associação do localizador usando lsregister -kill -seed. Nunca fiz isso, sem dizer quanto dano isso causará ao resto do seu sistema. Provavelmente você deseja cancelar o registro, editar as listas e, em seguida, matar e reenviar o banco de dados. Não me surpreenderia se o cancelamento de registro não excluir a associação se você já tiver removido o plist, e o reenvio o adicionará novamente se você ainda não o tiver removido. Além disso, dessa forma, você não perderá todas as outras associações dos aplicativos ofensivos.

O que é pior, o Xcode poderia ter passado e definir o bit do pacote em todas as pastas. Acho que você teria que escrever um script usando GetFileInfoe SetFilepara digitalizar o disco e desfazê-los, o que é meio doloroso, mas factível. Os dedos cruzados nos bits do pacote permanecem não definidos. Use GetFileInfopara verificar testando alguns.

Old Pro
fonte
0

Eu acredito que você pode consertar isso usando

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

Teste-o em um antes de tentar em todos os outros, obviamente.

Se você precisar executar todos eles em uma determinada pasta:

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

deve fazer isso por você.

TJ Luoma
fonte
1
SetFile -a B define o bit do pacote. Na verdade, ele deve ser desativado: SetFile -a b. Mas isso não terá efeito, pois o Has bundlebit não está definido: GetFileInfo -ab foo.itmspretorna 0.
jaume