Проблема: папки .itmsp отображаются в виде файлов
Finder обрабатывает папки .itmsp как пакеты , то есть как если бы они были одним файлом. Например, в представлении столбца все, что содержится в папке .itmsp, невидимо, отображается только значок документа:
Программа Finder считает каталог пакетом, если выполняется любое из следующих условий (из Руководства по программированию пакета ):
Каталог имеет известное расширение имени файла: .app, .bundle, .framework, .plugin, .kext и т. Д. (Как определено в /System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist
. Это двоичный список, откройте его с помощью Xcode:) open -a Xcode Info.plist
.
У каталога есть расширение, которое в некоторых других заявках приложения представляет тип пакета (ищите com.apple.package
в выходных данных, mdls -name kMDItemContentTypeTree <foldername>
чтобы узнать.)
В каталоге установлен бит пакета (если 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, выполните следующие действия:
Откройте Automator в папке «Приложения» и выберите « Приложение» :
Выберите Utilities в списке Library, выберите Run Shell Script и перетащите его на панель справа:
Замените содержимое скрипта по умолчанию на exit 0
:
Сохраните приложение как itmspOpener:
Закрыть Automator.
Выберите itmspOpener.app
и покажите его содержимое:
Найдите Contents> Info.plist и откройте его в вашем любимом редакторе:
Замените эти разделы в 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.
Свяжите файл .itmsp itmspOpener
и нажмите кнопку Change All...:
Сбросить базу данных 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/
.)
Создайте папку .itmsp и перечислите ее свойства:
$ mkdir foo3.itmsp
$ mdls -name kMDItemContentTypeTree foo3.itmsp/
kMDItemContentTypeTree = (
"public.folder",
"public.directory",
"public.item"
)
Поскольку база данных Launch Services была сброшена, теперь Finder показывает папки .itmsp как папки.
Откройте, itmspOpener.app
чтобы загрузить свой plist файл и зарегистрируйтесь com.apple.itunes-producer.itmsp
:
$ open ~/Desktop/itmspOpener.app
Начало Application Loader.app
:
$ open '/Applications/Xcode.app/Contents/Applications/Application Loader.app'
Папка foo3.itmsp
должна все еще отображаться как папка.
Проверьте свойства папки еще раз:
$ mdls -name kMDItemContentTypeTree foo3.itmsp/
kMDItemContentTypeTree = (
"public.directory",
"public.item",
"public.content"
)
com.apple.package
не был добавлен в атрибуты метаданных папки, поэтому Finder по-прежнему отображает папки .itmsp как папки!
Автоматизированное решение: отображение папок .itmsp в виде папок после входа в систему
Чтобы отобразить папки .itmsp как папки после входа в систему:
Создайте itmspOpener.app
и измените его, Info.plist
как описано выше.
Создайте /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
имеют первостепенное значение. Если вы не видите желаемого результата, попробуйте другие задержки.
Создать /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 &
Установите оба исполняемых скрипта:
$ sudo chmod a+x /usr/local/bin/itmspTypeLoader /usr/local/bin/itmspTypeLoaderLauncher
Установить /usr/local/bin/itmspTypeLoaderLauncher
как хук входа в систему :
$ sudo defaults write com.apple.loginwindow LoginHook /usr/local/bin/itmspTypeLoaderLauncher
Перезагрузитесь, чтобы изменения вступили в силу. После входа в систему вы должны увидеть это:
и lsregister -dump
должен показать, что itmspOpener.app
s UTExportedTypeDeclarations
имеет приоритет над 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
--------------------------------------------------------
Вы видите inactive
флаг, установленный в типе экспорта Application Loader.app? Мы победили загрузчик приложений.
Кислотный тест: папки .itmsp по-прежнему отображаются как таковые после обновления iTunes
Я недавно обновил Xcode:
и может подтвердить, что папки .itmsp были показаны как папки во время обновления:
и потом:
Частичное решение: пакет покажет содержимое при двойном щелчке
Как отмечалось ранее, процедура, описанная выше, не будет работать с произвольными папками, которые отображаются как пакеты Finder.
Однако, если вы просто хотите иметь возможность дважды щелкнуть пакет, чтобы открыть его, есть способ сделать это с помощью одного bash
сценария и Automator:
Сценарий создает скрытую временную папку внутри пакета, открывает ее в Finder (таким образом, раскрывая пакет как папку), а затем удаляет временную папку.
Замечания:
Вместо этого сценарий может создать скрытый временный файл. Тем не менее, я предпочитаю создавать папки, потому что rmdir
удаляет только пустые папки, в то время как rm
удаляет любой файл, так что если, по какой-то причине. скрипт разрушает, будут удалены только пустые папки, что, вероятно, не так плохо, как если бы файлы были удалены.
Automator объединяет скрипт в приложение, которое будет связано с файлами пакета.
Это шаги для создания такого приложения. Я буду использовать файлы .itmsp в качестве примера типа пакета в пояснении ниже:
Откройте Automator в папке «Приложения» и выберите « Приложение» :
Выберите Utilities в списке Library, выберите Run Shell Script и перетащите его на панель справа:
Установите Pass вход в качестве аргументов :
Замените содержимое скрипта по умолчанию на это:
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
Сохраните приложение как itmspOpener:
Закрыть Automator.
Теперь у вас есть приложение, которое может открывать файлы .itmsp в виде папок, если они связаны с ним.
Существует косметическая проблема: связанные файлы будут иметь стандартный белый значок документа:
Давайте исправим это тоже:
Убедитесь, что Automator закрыт.
Выберите itmspOpener и покажите его содержимое:
Найдите Contents> Info.plist и откройте его в вашем любимом редакторе:
Замените значение этого ключа в CFBundleDocumentTypes
массиве:
<key>CFBundleTypeName</key>
<string>itmsp folder</string>
и добавьте этот ключ:
<key>CFBundleTypeIconFile</key>
<string>folder</string>
Теперь раздел выглядит так:
Переключитесь в Finder, выберите папку, нажмите ⌘I, выберите значок папки в левом верхнем углу и скопируйте его с помощью ⌘C:
Откройте «Просмотр» и выберите «Файл»> «Создать из буфера обмена». Сохраните файл как folder.icns
:
Скопировать folder.icns
в itmspOpener/Contents/Resources
:
Свяжите файл .itmsp itmspOpener
и нажмите кнопку Change All...:
Значок файлов .itmsp должен измениться на папку, или, по крайней мере, я так подумал: к сожалению, это не так. Поэтому я переместил приложение itmspOpener в другое место (я создал временную папку на рабочем столе, переместил ее туда и обратно на рабочий стол). Это обновило информацию о значке в Finder:
Теперь дважды щелкните файл .itmsp и просмотрите его как папку: