Восстановить ассоциацию типов файлов

12

Я иногда работаю с пакетами iTunes Music Store. Эти пакеты имеют .itmspрасширение. Мол .app, .itmspпо сути, это контейнерный каталог. .itmspпапки содержат XML и медиа-файлы.

Последнее обновление Xcode и / или Mac OS X (Xcode 4.6.1 в Mac OS 10.8.3) похитило ассоциацию типов файлов для каталогов с .itmspрасширением. Ранее они рассматривались как обычные папки - для просмотра изнутри не требуется двойной щелчок. Теперь я должен дважды щелкнуть их, чтобы взаимодействовать с ними. Когда я это делаю, программа под названием Application Loader пытается открыть их. Чтобы увидеть внутри, я должен щелкнуть правой кнопкой мыши и выбрать «Показать содержимое пакета». Я имею дело с тысячами этих файлов в любой момент времени, так что это не сработает.

Я попытался изменить или удалить сопоставление типов файлов, используя Get Info и RCDefaultApp. Ни то, ни другое не работает. Удаление ассоциации типов файлов просто превращает .itmspкаталоги в пустые файлы. Как и удаление приложения Loader.app полностью. В любом случае я все еще не могу просмотреть содержимое без щелчка правой кнопкой мыши.

Ранее принятый ответ какое-то время работал lsregister -u /Applications/Contents/Applications/Application\ Loader.app/хорошо : он перестал работать, так как я обновил XCode и / или Mac OS X. Если у вас установлен XCode, вы сможете проверить это самостоятельно, назвав каталог foo.itmsp.

Как сделать так, чтобы .itmspфайлы снова рассматривались как папки?

michaelmichael
источник
Вы пытались перетащить файл на иконку приложения Xcode и посмотреть, делает ли он то, что вы хотите?
MrDaniel
Спасибо за предложение. Это не относится к рассматриваемой проблеме, поэтому я постараюсь отредактировать свой вопрос, чтобы уточнить мои намерения.
Майкл Майкл
1
Какую версию OS X вы используете? Какая версия Xcode?
Старый Pro
Я удалил свой ответ, который удалил типы из CFBundleDocumentTypes и уничтожил их в базе данных службы запуска. Это работает какое-то время, но, кажется, в какой-то момент позже оно вновь подтверждает себя.
Мархунте

Ответы:

11

Проблема: папки .itmsp отображаются в виде файлов

Finder обрабатывает папки .itmsp как пакеты , то есть как если бы они были одним файлом. Например, в представлении столбца все, что содержится в папке .itmsp, невидимо, отображается только значок документа:

введите описание изображения здесь

Программа Finder считает каталог пакетом, если выполняется любое из следующих условий (из Руководства по программированию пакета ):

  1. Каталог имеет известное расширение имени файла: .app, .bundle, .framework, .plugin, .kext и т. Д. (Как определено в /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist. Это двоичный список, откройте его с помощью Xcode:) open -a Xcode Info.plist.

  2. У каталога есть расширение, которое в некоторых других заявках приложения представляет тип пакета (ищите com.apple.packageв выходных данных, mdls -name kMDItemContentTypeTree <foldername>чтобы узнать.)

  3. В каталоге установлен бит пакета (если GetFileInfo -ab <foldername>возвращается 1, он установлен).

Случай 2. применяется к папкам .itmsp: Application Loader.appэкспортирует тип com.apple.itunes-producer.itmspи устанавливает его для соответствия 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>

Решение: повторно объявить тип com.apple.itunes-producer.itmsp

Решением было бы повторно объявить тип com.apple.itunes-producer.itmspи расширение itmspкак папку и заставить Launch Services использовать измененное объявление типа.

Важная заметка:

Хотя это решение надежно решает проблему OP, предлагаемое решение при применении к другим пакетам не отображает их в виде папок.

Я обнаружил, что предложенное решение, похоже, работает только с типами файлов, объявленными приложениями, расположенными в нестандартном пути приложения.

Это тот случай с Application Loader.app, который находится в /Applications/Xcode.app/Contents/Applications/.

Если вы заинтересованы в частичном решении, проверьте конец этого ответа.

Чтобы папки .itmsp отображались в виде папок с помощью Finder, выполните следующие действия:

  1. Откройте Automator в папке «Приложения» и выберите « Приложение» :

    введите описание изображения здесь

  2. Выберите Utilities в списке Library, выберите Run Shell Script и перетащите его на панель справа:

    введите описание изображения здесь

  3. Замените содержимое скрипта по умолчанию на exit 0:

    введите описание изображения здесь

  4. Сохраните приложение как itmspOpener:

    введите описание изображения здесь

  5. Закрыть Automator.

  6. Выберите itmspOpener.appи покажите его содержимое:

    введите описание изображения здесь

  7. Найдите Contents> Info.plist и откройте его в вашем любимом редакторе:

    введите описание изображения здесь

  8. Замените эти разделы в 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>
    

    Примечание: почему kUTTypeDirectoryвместо public.directoryв UTExportedTypeDeclarations? Из документации Apple : Важно: При использовании системных UTI в вашем коде вы должны использовать константы, определенные UTCoreTypes.hв платформе Launch Services, когда они доступны, а не фактические строки UTI. Например, передайте kUTTypeApplication, а не «com.apple.application». «Объявленные системой унифицированные идентификаторы типов» перечисляют эти константы в дополнение к строкам UTI.

  9. Свяжите файл .itmsp itmspOpenerи нажмите кнопку Change All...:

    введите описание изображения здесь

  10. Сбросить базу данных Launch Services:

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

    (на OS X 10.8 lsregisterнаходится в /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/.)

  11. Создайте папку .itmsp и перечислите ее свойства:

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

    Поскольку база данных Launch Services была сброшена, теперь Finder показывает папки .itmsp как папки.

  12. Откройте, itmspOpener.appчтобы загрузить свой plist файл и зарегистрируйтесь com.apple.itunes-producer.itmsp:

    $ open ~/Desktop/itmspOpener.app
    
  13. Начало Application Loader.app:

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

    Папка foo3.itmspдолжна все еще отображаться как папка.

  14. Проверьте свойства папки еще раз:

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

    com.apple.package не был добавлен в атрибуты метаданных папки, поэтому Finder по-прежнему отображает папки .itmsp как папки!

Автоматизированное решение: отображение папок .itmsp в виде папок после входа в систему

Чтобы отобразить папки .itmsp как папки после входа в систему:

  1. Создайте itmspOpener.appи измените его, Info.plistкак описано выше.

  2. Создайте /usr/local/bin/itmspTypeLoaderс этим содержимым (переменная itmspOpenerуказывает на место, где itmspOpener.appнаходится, измените при необходимости):

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

    И sleep 15до, и после бега lsregisterимеют первостепенное значение. Если вы не видите желаемого результата, попробуйте другие задержки.

  3. Создать /usr/local/bin/itmspTypeLoaderLauncherс этим содержанием:

    #!/bin/bash
    
    # $1 returns the short name of the user who is logging in
    su - $1 -c /usr/local/bin/itmspTypeLoader &
    
  4. Установите оба исполняемых скрипта:

    $ sudo chmod a+x /usr/local/bin/itmspTypeLoader /usr/local/bin/itmspTypeLoaderLauncher 
    
  5. Установить /usr/local/bin/itmspTypeLoaderLauncherкак хук входа в систему :

    $ sudo defaults write com.apple.loginwindow LoginHook /usr/local/bin/itmspTypeLoaderLauncher
    
  6. Перезагрузитесь, чтобы изменения вступили в силу. После входа в систему вы должны увидеть это:

    введите описание изображения здесь

    и lsregister -dumpдолжен показать, что itmspOpener.apps UTExportedTypeDeclarationsимеет приоритет над Application Loader.apps:

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

    Вы видите inactiveфлаг, установленный в типе экспорта Application Loader.app? Мы победили загрузчик приложений.

Кислотный тест: папки .itmsp по-прежнему отображаются как таковые после обновления iTunes

Я недавно обновил Xcode:

введите описание изображения здесь

и может подтвердить, что папки .itmsp были показаны как папки во время обновления:

введите описание изображения здесь

и потом:

введите описание изображения здесь

Частичное решение: пакет покажет содержимое при двойном щелчке

Как отмечалось ранее, процедура, описанная выше, не будет работать с произвольными папками, которые отображаются как пакеты Finder.

Однако, если вы просто хотите иметь возможность дважды щелкнуть пакет, чтобы открыть его, есть способ сделать это с помощью одного bashсценария и Automator:

  • Сценарий создает скрытую временную папку внутри пакета, открывает ее в Finder (таким образом, раскрывая пакет как папку), а затем удаляет временную папку.

    Замечания:

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

  • Automator объединяет скрипт в приложение, которое будет связано с файлами пакета.

Это шаги для создания такого приложения. Я буду использовать файлы .itmsp в качестве примера типа пакета в пояснении ниже:

  1. Откройте Automator в папке «Приложения» и выберите « Приложение» :

    введите описание изображения здесь

  2. Выберите Utilities в списке Library, выберите Run Shell Script и перетащите его на панель справа:

    введите описание изображения здесь

  3. Установите Pass вход в качестве аргументов :

    введите описание изображения здесь

  4. Замените содержимое скрипта по умолчанию на это:

    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. Сохраните приложение как itmspOpener:

    введите описание изображения здесь

  6. Закрыть Automator.

Теперь у вас есть приложение, которое может открывать файлы .itmsp в виде папок, если они связаны с ним.

Существует косметическая проблема: связанные файлы будут иметь стандартный белый значок документа:

введите описание изображения здесь

Давайте исправим это тоже:

  1. Убедитесь, что Automator закрыт.

  2. Выберите itmspOpener и покажите его содержимое:

    введите описание изображения здесь

  3. Найдите Contents> Info.plist и откройте его в вашем любимом редакторе:

    введите описание изображения здесь

  4. Замените значение этого ключа в CFBundleDocumentTypesмассиве:

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

    и добавьте этот ключ:

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

    Теперь раздел выглядит так:

    введите описание изображения здесь

  5. Переключитесь в Finder, выберите папку, нажмите I, выберите значок папки в левом верхнем углу и скопируйте его с помощью C:

    введите описание изображения здесь

  6. Откройте «Просмотр» и выберите «Файл»> «Создать из буфера обмена». Сохраните файл как folder.icns:

    введите описание изображения здесь

  7. Скопировать folder.icnsв itmspOpener/Contents/Resources:

    введите описание изображения здесь

  8. Свяжите файл .itmsp itmspOpenerи нажмите кнопку Change All...:

    введите описание изображения здесь

Значок файлов .itmsp должен измениться на папку, или, по крайней мере, я так подумал: к сожалению, это не так. Поэтому я переместил приложение itmspOpener в другое место (я создал временную папку на рабочем столе, переместил ее туда и обратно на рабочий стол). Это обновило информацию о значке в Finder:

введите описание изображения здесь

Теперь дважды щелкните файл .itmsp и просмотрите его как папку:

введите описание изображения здесь

Жауме
источник
Это очень впечатляет ... НО, похоже, есть одна проблема: если Finder находится в виде столбца (мой предпочтительный тип представления), все, что содержится в .itmspпапке, невидимо. Я не могу разобраться почему, но это так. Кроме того, если бы у меня были мои барабанщики, вам бы не пришлось дважды щелкать файл, чтобы посмотреть внутрь, ну да ладно.
Майкл Майкл
1
Вы правы. Я не ожидал, что вы используете представление столбцов, хотя должен сказать, что это имеет смысл, когда имеешь дело с тысячами папок .itmsp. Но я нашел способ решить эту проблему - заставить Finder обрабатывать папки .itmsp как папки. Взгляните на мою правку (или перейдите непосредственно к последнему абзацу под названием Решение, но не забудьте сначала изменить его в Info.plist, как описано в параграфе The trick.)
jaume
Невероятно! Спасибо за ответ. Это очень интересный взгляд на некоторые вещи, которые делают Finder и OS X галочкой.
Майкл Майкл
Спасибо, я рад, что вы нашли это полезным! (Я отредактирую ответ позже, чтобы улучшить читаемость и придать ему большую структуру.)
Jaume
Я наконец нашел время, чтобы отредактировать ответ. Я изменил порядок абзацев и добавил доказательства того, что решение, описанное в моем ответе, не зависит от обновлений iTunes.
Jaume
7

Один из вариантов - отменить регистрацию Application Loader lsregister -u /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/, но он снова регистрируется, если он открывается, перестраивается база данных Launch Services или, возможно, обновляется Xcode.

Вы также можете закомментировать записи в словарях CFBundleDocumentTypes и UTExportedTypeDeclarations /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Info.plistи запустить их lsregister -f /Applications/Xcode.app/Contents/Applications/Utilities/Application\ Loader.app/. Это не делает недействительной подпись кода XCode, но изменения могут быть перезаписаны обновлениями.

Полный путь к lsregister находится /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregisterв 10.5 и позже.

LRI
источник
Вы уверены, что отмена регистрации приложения после его изменения Info.plistприведет к отмене регистрации типов файлов, удаленных из списка? Я могу вообразить, что это работает, и я могу легко вообразить, что это терпит неудачу. тоже.
Old Pro
@OldPro Ага, lsregister -u $app && lsregister $appкажется, применяет изменения в Info.plist, по крайней мере, в этом случае.
Lri
Это невероятный ответ - имейте в виду, что в следующий раз, когда вы обновите Xcode - у вас может получиться Загрузчик приложений, который регистрирует по умолчанию, CFBundleDocumentTypesтак что вы можете просто удалить этот «инструмент», когда он появится, если он вам не нужен, и / или устал от его модификации.
bmike
2

Вот соответствующий отрывок из компании Apple documenation о пучках ( курсив добавлен )

Как система идентифицирует пакеты и пакеты

Искатель считает каталог пакетом, если выполняется любое из следующих условий:

  • Каталог имеет известное расширение имени файла: .app, .bundle, .framework, .plugin, .kext и т. Д.
  • У каталога есть расширение, которое в некоторых других заявках приложения представляет тип пакета; см. « Пакеты документов ».
  • В каталоге установлен бит пакета.

Предпочтительный способ указать пакет - дать каталогу пакета известное расширение имени файла. По большей части Xcode заботится об этом за вас , предоставляя шаблоны, которые применяют правильное расширение. Все, что вам нужно сделать, это создать проект Xcode соответствующего типа.

Почти наверняка Xcode представляет, что он утверждает, что .itmspпредставляет тип пакета, как описано в Пакетах документов . Так что, возможно, удалив это расширение из XCode, у меня Info.plistполучится, но я подозреваю, что как только эта ассоциация будет замечена Finder, удаление его из XCode не отменит его. Какие «рекомендуемые приложения» вы получаете, если щелкнуть правой кнопкой мыши «Открыть с помощью ...»? Вы должны проверить все их Info.plists.

Я предлагаю посмотреть, можете ли вы избежать использования lsregister -uрегистрации для любых заявленных приложений .itmsp. В противном случае вам, возможно, придется удалить .itmspвсе списки, а затем уничтожить всю базу данных ассоциации поиска с помощью lsregister -kill -seed. Никогда не делал этого, не сообщая, какой ущерб это нанесет остальной части вашей системы. Возможно, вы хотите отменить регистрацию, затем отредактировать списки, затем убить и заново заполнить базу данных. Меня не удивит, если незарегистрированная не удалит ассоциацию, если вы уже удалили ее из списка, и повторно запишет ее, если вы еще не удалили ее. Кроме того, таким образом вы не потеряете все другие ассоциации для оскорбительных приложений.

Что еще хуже, XCode мог пройти и установить бит пакета на все папки. Полагаю, тогда вам придется написать сценарий, используя GetFileInfoи SetFileдля сканирования диска, и отменить те, что немного болезненно, но выполнимо. Пальцы, пересекшие сверток, остаются неустановленными. Используйте, GetFileInfoчтобы проверить, протестировав несколько.

Старый Про
источник
0

Я считаю, что вы можете это исправить, используя

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

Проверьте это на одном, прежде чем попробовать на всех остальных, очевидно.

Если вам нужно запустить все из них в заданной папке:

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

должен сделать это для вас.

Ти Джей Луома
источник
1
SetFile -a B устанавливает бит пакета На самом деле это должно быть отключено SetFile -a b. Но это не будет иметь эффекта, так как Has bundleбит не установлен: GetFileInfo -ab foo.itmspвозвращается 0.
Jaume