如何使用命令行工具为Mac OS X创建美观的DMG?
我需要为Mac应用程序创建一个不错的安装程序。我希望它是具有预定义大小,布局和背景图像的磁盘映像(DMG)。
我需要在脚本中以编程方式进行此操作,以将其集成到现有的构建系统中(实际上更多的是打包系统,因为它仅创建安装程序。构建是单独进行的)。
我已经使用" hdiutil"完成了DMG的创建,但我还没有发现如何进行图标布局和指定背景位图。
解决方案
不要去那作为Mac的长期开发人员,我可以向我们保证,没有任何一种解决方案能很好地发挥作用。我尝试了很多解决方案,但是它们都不是很好。我认为问题在于Apple并未真正记录必要数据的元数据格式。
这是我很长一段时间以来一直做的非常成功的方法:
- 创建一个新的DMG,writeable(!),其大小足以容纳所需的二进制文件和其他自述文件(稀疏文件可能起作用)。
- 安装DMG并在Finder中或者使用任何适合工具手动为其提供布局(请参见底部的FileStorm链接以获取良好的工具)。背景图片通常是我们放入DMG上隐藏文件夹(" .something")中的图片。将应用程序副本放在那里(任何版本,甚至是过时的版本都可以)。复制我们想要的其他文件(别名,自述文件等),同样,过时的版本也可以。确保图标具有正确的尺寸和位置(IOW,以所需的方式布局DMG)。
- 再次卸载DMG,所有设置应立即存储。
- 它装入副本。
- 它将所有文件替换为最新文件(例如,构建后使用最新的应用程序)。我们可以在命令行上简单地使用mv或者ditto。请注意,当我们像这样替换文件时,图标将保持不变,位置将保持不变,除了文件(或者目录)内容之外的所有内容都将保持不变(至少对于同上,我们通常在该任务中使用) 。当然,我们也可以用另一幅图像替换背景图像(只需确保它具有相同的尺寸)。
- 替换文件后,使脚本再次卸载DMG副本。
- 最后,调用hdiutil将可写文件转换为压缩的DMG(例如不可写文件)。
这种方法听起来可能不是最佳方法,但是请相信我,它在实践中确实很好用。我们甚至可以将原始DMG(DMG模板)置于版本控制下(例如SVN),因此,如果我们不小心更改/销毁了它,则可以返回到仍然可以的版本。我们可以将DMG模板以及属于DMG的所有其他文件(自述文件,URL文件,背景图像)一起添加到Xcode项目中,所有这些都在版本控制下,然后创建一个目标(例如,名为" Create DMG"的外部目标)然后运行上面的DMG脚本,并将旧主要目标添加为从属目标。我们可以使用脚本中的$ {SRCROOT}访问Xcode树中的文件(始终是产品的源根目录),也可以使用$ {BUILT_PRODUCTS_DIR}访问Xcode产品(始终是Xcode创建生成结果的目录) 。
结果:实际上,Xcode可以在构建结束时生成DMG。准备发布的DMG。我们不仅可以通过这种方式轻松创建relase DMG,而且实际上还可以使用命令行中的xcodebuild(例如,每晚自动生成)以自动化的过程(如果需要,可以在无头服务器上)进行。
关于模板的初始布局,FileStorm是一个很好的工具。它是商业性的,但功能强大且易于使用。普通版不到20美元,因此价格实在实惠。也许可以自动化FileStorm来创建DMG(例如通过AppleScript),但从未尝试过,但是一旦找到了理想的模板DMG,就可以很容易地为每个发行版进行更新。
对于那些对此主题感兴趣的人,我应该提到如何创建DMG:
hdiutil create XXX.dmg -volname "YYY" -fs HFS+ -srcfolder "ZZZ"
在哪里
XXX == disk image file name (duh!) YYY == window title displayed when DMG is opened ZZZ == Path to a folder containing the files that will be copied into the DMG
有一个名为create-dmg的Bash小脚本,可使用自定义背景,自定义图标位置和卷名来构建精美的DMG。
我是在多年前为当时经营的公司建立的。从那时起,它就一直依靠别人的贡献生存下来,据报道效果很好。
还有一个node-appdmg,它看起来像是基于Node.js的更现代,更积极的尝试。还要检查一下。
经过大量研究,我想出了这个答案,在此我将其作为我自己问题的答案,以供参考:
- 确保在"系统偏好设置">"通用访问权限"中选中"启用辅助设备的访问权限"。 AppleScript必须运行。进行此更改后,我们可能必须重新引导(否则在Mac OS X Server 10.4上将不起作用)。
- 创建一个R / W DMG。它必须大于结果。在此示例中,bash变量" size"包含以Kb为单位的大小,并且" source" bash变量中文件夹的内容将被复制到DMG中:
hdiutil create -srcfolder "${source}" -volname "${title}" -fs HFS+ \ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${size}k pack.temp.dmg
- 挂载磁盘映像,并存储设备名称(此操作后,我们可能要使用sleep几秒钟):
device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \ egrep '^/dev/' | sed 1q | awk '{print }')
- 将背景图片(以PNG格式)存储在DMG中名为" .background"的文件夹中,并将其名称存储在" backgroundPictureName"变量中。
- 使用AppleScript设置视觉样式(.app的名称必须在bash变量" applicationName"中,根据需要将变量用于其他属性):
echo ' tell application "Finder" tell disk "'${title}'" open set current view of container window to icon view set toolbar visible of container window to false set statusbar visible of container window to false set the bounds of container window to {400, 100, 885, 430} set theViewOptions to the icon view options of container window set arrangement of theViewOptions to not arranged set icon size of theViewOptions to 72 set background picture of theViewOptions to file ".background:'${backgroundPictureName}'" make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} set position of item "'${applicationName}'" of container window to {100, 100} set position of item "Applications" of container window to {375, 100} update without registering applications delay 5 close end tell end tell ' | osascript
- 通过正确设置权限,压缩和释放DMG,最终完成DMG:
chmod -Rf go-w /Volumes/"${title}" sync sync hdiutil detach ${device} hdiutil convert "/pack.temp.dmg" -format UDZO -imagekey zlib-level=9 -o "${finalDMGName}" rm -f /pack.temp.dmg
在Snow Leopard上,上面的applescript无法正确设置图标位置,这似乎是Snow Leopard的错误。一种解决方法是在设置图标后简单地调用关闭/打开,即:
.. set position of item "'${applicationName}'" of container window to {100, 100} set position of item "Applications" of container window to {375, 100} close open
.DS_Store文件将Windows设置存储在Mac中。 Windows设置包括图标布局,窗口背景,窗口大小等。在创建用于装入图像的窗口时需要.DS_Store文件,以保留文件和窗口背景的排列。
创建.DS_Store文件后,我们可以将其复制到创建的安装程序(DMG)中。
我的应用程序DropDMG是创建带有背景图片,图标布局,自定义卷图标和软件许可协议的磁盘映像的简便方法。可以从构建系统通过" dropdmg"命令行工具或者AppleScript对其进行控制。如果需要,可以将图片和许可证RTF文件存储在版本控制系统下。