问题:.itmsp文件夹显示为文件
Finder将.itmsp文件夹视为包,即就像它们是单个文件一样。例如,在列视图中,.itmsp文件夹中包含的所有内容都是不可见的,仅显示文档图标:
如果满足以下任一条件,则Finder会将目录视为一个包(来自Bundle编程指南):
该目录具有已知的文件扩展名:.app,.bundle,.framework,.plugin,.kext等(如。中的定义/System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist
。这是一个二进制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
为文件夹,并强制启动服务使用修改后的类型声明。
重要的提示:
尽管它可以可靠地解决OP的问题,但所提出的解决方案在应用于其他程序包时不会将其显示为文件夹。
我发现,提出的解决方案似乎仅适用于位于非标准应用程序路径中的应用程序声明的文件类型。
Application Loader.app
位于的就是这种情况/Applications/Xcode.app/Contents/Applications/
。
如果您对部分解决方案感兴趣,请查看此答案的结尾。
要使Finder将.itmsp文件夹显示为文件夹,请执行以下步骤:
在“应用程序”文件夹中打开Automator,然后选择“ 应用程序”:
在“库”列表中选择“实用程序”,选择“运行Shell脚本”并将其拖到右侧窗格中:
将默认脚本内容替换为exit 0
:
将应用程序另存为itmspOpener:
关闭自动器。
选择itmspOpener.app
并显示其内容:
找到目录> 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
in UTExportedTypeDeclarations
?根据Apple的文档:重要提示:在代码中使用系统定义的UTI时,应使用UTCoreTypes.h
Launch Services框架中定义的常量(如果可用),而不是实际的UTI字符串。例如,传递kUTTypeApplication而不是“ com.apple.application”。“系统声明的统一类型标识符”除列出了UTI字符串外,还列出了这些常量。
将.itmsp文件关联到itmspOpener
并按下按钮Change All...:
重置启动服务数据库:
$ 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"
)
因为启动服务数据库已重置,所以现在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
的UTExportedTypeDeclarations
在优先Application Loader.app
的:
$ 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的类型导出中看到设置的标志?我们击败了Application Loader。
酸性测试:.itmsp文件夹在iTunes更新后仍显示为
我最近更新了Xcode:
并可以确认.itmsp文件夹在更新过程中显示为文件夹:
然后:
部分解决方案:双击该软件包将显示内容
如前所述,上面详细介绍的过程不适用于Finder作为包显示的任意文件夹。
但是,如果只想双击一个程序包将其打开,则可以使用一种bash
脚本和Automator来实现:
这些是创建此类应用程序的步骤。在以下说明中,我将使用.itmsp文件作为包类型示例:
在“应用程序”文件夹中打开Automator,然后选择“ 应用程序”:
选择工具在库列表中,选择运行shell脚本并将其拖动到右边的窗格:
将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:
关闭自动器。
现在,您有了一个可以将.itmsp文件作为文件夹打开的应用程序。
有一个外观上的问题:就目前而言,关联文件将带有标准的白色文档图标:
我们也修复此问题:
确保Automator已关闭。
选择itmspOpener并显示其内容:
找到目录> 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文件,并观看它作为文件夹打开: