macos 如何使用命令行工具為Mac OS X創建漂亮的DMG?




scripting installer (12)

如果你想設置自定義音量圖標,然後使用下面的命令

/*Add a drive icon*/
cp "/Volumes/customIcon.icns" "/Volumes/dmgName/.VolumeIcon.icns"  


/*SetFile -c icnC will change the creator of the file to icnC*/
SetFile -c icnC /<your path>/.VolumeIcon.icns

現在創建讀/寫dmg

/*to set custom icon attribute*/
SetFile -a C /Volumes/dmgName

我需要為Mac應用程序創建一個很好的安裝程序。 我希望它是一個磁盤映像(DMG),具有預定義的大小,佈局和背景圖像。

我需要在腳本中以編程方式執行此操作,以便集成到現有的構建系統中(實際上更多的是包構建系統,因為它只創建安裝程序,而構建則單獨完成)。

我已經使用“hdiutil”完成了DMG創建,但我還沒有發現的是如何製作圖標佈局並指定背景位圖。


這些答案太複雜,時代也變了。 下面的10.9就好了,權限是正確的,它看起來不錯。

從目錄創建一個只讀DMG

#!/bin/sh
# create_dmg Frobulator Frobulator.dmg path/to/frobulator/dir [ 'Your Code Sign Identity' ]
set -e

VOLNAME="$1"
DMG="$2"
SRC_DIR="$3"
CODESIGN_IDENTITY="$4"

hdiutil create -srcfolder "$SRC_DIR" \
  -volname "$VOLNAME" \
  -fs HFS+ -fsargs "-c c=64,a=16,e=16" \
  -format UDZO -imagekey zlib-level=9 "$DMG"

if [ -n "$CODESIGN_IDENTITY" ]; then
  codesign -s "$CODESIGN_IDENTITY" -v "$DMG"
fi

使用圖標創建只讀DMG(圖標類型)

#!/bin/sh
# create_dmg_with_icon Frobulator Frobulator.dmg path/to/frobulator/dir path/to/someicon.icns [ 'Your Code Sign Identity' ]
set -e
VOLNAME="$1"
DMG="$2"
SRC_DIR="$3"
ICON_FILE="$4"
CODESIGN_IDENTITY="$5"

TMP_DMG="$(mktemp -u -t XXXXXXX)"
trap 'RESULT=$?; rm -f "$TMP_DMG"; exit $RESULT' INT QUIT TERM EXIT
hdiutil create -srcfolder "$SRC_DIR" -volname "$VOLNAME" -fs HFS+ \
               -fsargs "-c c=64,a=16,e=16" -format UDRW "$TMP_DMG"
TMP_DMG="${TMP_DMG}.dmg" # because OSX appends .dmg
DEVICE="$(hdiutil attach -readwrite -noautoopen "$TMP_DMG" | awk 'NR==1{print$1}')"
VOLUME="$(mount | grep "$DEVICE" | sed 's/^[^ ]* on //;s/ ([^)]*)$//')"
# start of DMG changes
cp "$ICON_FILE" "$VOLUME/.VolumeIcon.icns"
SetFile -c icnC "$VOLUME/.VolumeIcon.icns"
SetFile -a C "$VOLUME"
# end of DMG changes
hdiutil detach "$DEVICE"
hdiutil convert "$TMP_DMG" -format UDZO -imagekey zlib-level=9 -o "$DMG"
if [ -n "$CODESIGN_IDENTITY" ]; then
  codesign -s "$CODESIGN_IDENTITY" -v "$DMG"
fi

如果還有其他事情需要發生,最簡單的事情就是創建SRC_DIR的臨時副本,並在創建DMG之前對其進行更改。


我發現這個偉大的Mac應用程序來自動化這個過程 - http://www.araelium.com/dmgcanvas/如果你正在為你的Mac應用程序創建dmg安裝程序,你一定要看看


我還需要使用命令行方法來“編程地在腳本中”進行包裝和dmg創建。 我迄今發現的最佳答案是來自Adium項目的“發布構建框架”(參見R1)。 有一個自定義腳本(AdiumApplescriptRunner)允許您避免OSX WindowsServer GUI交互。 “osascript applescript.scpt”方法要求您以構建器身份登錄並從命令行vt100會話運行dmg創建。

OSX軟件包管理系統與其他可輕鬆系統地完成這項任務的Unixen相比並不那麼先進。

R1: http://hg.adium.im/adium-1.4/file/00d944a3ef16/Releasehttp://hg.adium.im/adium-1.4/file/00d944a3ef16/Release


我的應用程序DropDMG是一種用背景圖片,圖標佈局,自定義音量圖標和軟件許可證協議創建磁盤映像的簡單方法。 它可以通過構建系統通過“dropdmg”命令行工具或AppleScript進行控制。 如果需要,圖片和許可證RTF文件可以存儲在您的版本控制系統下。



不要去那裡。 作為一名長期的Mac開發人員,我可以向你保證,沒有任何解決方案能夠很好地工作。 我嘗試了很多解決方案,但都不太好。 我認為問題在於蘋果沒有真正記錄必要數據的元數據格式。

以下是我很長一段時間的做法,非常成功:

  1. 創建一個新的DMG,可寫(!),足夠大以容納預期的二進製文件和額外的文件,如自述文件(稀疏可能工作)。

  2. 安裝DMG並在Finder中手動佈局或使用任何適合您的工具(請參見位於底部的FileStorm鏈接以獲取更好的工具)。 背景圖片通常是我們放入DMG的隱藏文件夾(“.something”)中的圖片。 把你的應用程序的副本放在那裡(任何版本,甚至過時的都可以)。 複製你想要的其他文件(別名,自述文件等),過時的版本也可以。 確保圖標具有合適的尺寸和位置(IOW,按您希望的方式佈置DMG)。

  3. 再次卸載DMG,所有設置都應該保存到現在。

  4. 編寫一個創建DMG腳本,其工作原理如下:

    • 它複製了DMG,所以原來的DMG再也不會被碰到。
    • 它裝載副本。
    • 它用所有最新的文件替換所有文件(例如最新的應用程序)。 你可以簡單地在命令行中使用mv或者ditto 。 請注意,當您替換這樣的文件時,圖標將保持不變,位置將保持不變,除文件(或目錄)內容以外的所有內容保持不變(至少與我們通常用於該任務的同上) 。 你當然也可以用另一個替換背景圖片(只要確保它具有相同的尺寸)。
    • 替換文件後,使腳本再次卸載DMG副本。
    • 最後,調用hdiutil將可寫入轉換為壓縮(並且不可寫)的DMG。

這種方法可能聽起來並不理想,但相信我,它在實踐中效果很好。 你甚至可以在版本控制(例如SVN)下放置原始的DMG(DMG模板),所以如果你意外地改變/銷毀它,你可以回到一個修訂版,它仍然可以。 您可以將DMG模板與屬於DMG的所有其他文件(自述文件,URL文件,背景圖像)一起添加到您的Xcode項目中,全部在版本控制下,然後創建一個目標(例如名為“創建DMG”的外部目標)然後運行上面的DMG腳本並將您的舊主目標添加為依賴目標。 您可以使用腳本中的$ {SRCROOT}訪問Xcode樹中的文件(始終是產品的源代碼根),您可以使用$ {BUILT_PRODUCTS_DIR}訪問構建產品(始終是Xcode創建構建結果的目錄) 。

結果:實際上Xcode可以在構建結束時生成DMG。 準備釋放的DMG。 你不僅可以用這種方式創建一個相對簡單的DMG,你可以在自動化過程(如果你喜歡的話在無頭服務器上)使用命令行的xcodebuild(例如自動夜間編譯)來實現。

關於模板的初始佈局, FileStorm是一個很好的工具。 它是商業的,但非常強大且易於使用。 正常版本不到20美元,所以它確實很實惠。 也許可以自動化FileStorm來創建一個DMG(例如通過AppleScript),從來沒有嘗試過,但是一旦你找到了完美的模板DMG,對於每個發行版都很容易更新它。


有一個名為create-dmg的小Bash腳本,用於create-dmg具有自定義背景,自定義圖標定位和卷名稱的花式DMG。

多年前,我為我當時經營的公司建立了它; 自那時以來,它在其他人的貢獻上存活下來,據報導效果很好。

還有github.com/LinusU/node-appdmg ,它看起來像基於Node.js的更現代和更主動的工作; 檢查出來。


我剛寫了一個新的(友好的)命令行實用程序來執行此操作。 它不依賴於Finder / AppleScript,或任何(不建議使用的)Alias Manager API,並且配置和使用都很簡單。

無論如何,任何有興趣的人都可以dmgbuild ; 該文檔可在Read The Docs上找到


通過提供這個答案來回答這個問題。

appdmg是一個簡單易用的開源命令行程序,可以根據簡單的json規範創建dmg文件。 看看官方網站上的自述文件:

github.com/LinusU/node-appdmg

快速示例:

  1. 安裝appdmg

    npm install -g appdmg
    
  2. 編寫一個json文件( spec.json

    {
      "title": "Test Title",
      "background": "background.png",
      "icon-size": 80,
      "contents": [
        { "x": 192, "y": 344, "type": "file", "path": "TestApp.app" },
        { "x": 448, "y": 344, "type": "link", "path": "/Applications" }
      ]
    }
    
  3. 運行程序

    appdmg spec.json test.dmg
    

(免責聲明我是appdmg的創造者)


對於那些對這個主題感興趣的人,我應該提到我如何創建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

我終於在我自己的項目中得到了這個工作(恰好在Xcode中)。 將這3個腳本添加到構建階段將自動為您的產品創建一個漂亮整潔的磁盤映像。 您所要做的就是構建您的項目,並且DMG將在您的產品文件夾中等待。

腳本1(創建臨時磁盤映像):

#!/bin/bash
#Create a R/W DMG

dir="$TEMP_FILES_DIR/disk"
dmg="$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.temp.dmg"

rm -rf "$dir"
mkdir "$dir"
cp -R "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app" "$dir"
ln -s "/Applications" "$dir/Applications"
mkdir "$dir/.background"
cp "$PROJECT_DIR/$PROJECT_NAME/some_image.png" "$dir/.background"
rm -f "$dmg"
hdiutil create "$dmg" -srcfolder "$dir" -volname "$PRODUCT_NAME" -format UDRW

#Mount the disk image, and store the device name
hdiutil attach "$dmg" -noverify -noautoopen -readwrite

腳本2(設置窗口屬性腳本):

#!/usr/bin/osascript
#get the dimensions of the main window using a bash script

set {width, height, scale} to words of (do shell script "system_profiler SPDisplaysDataType | awk '/Main Display: Yes/{found=1} /Resolution/{width=$2; height=$4} /Retina/{scale=($2 == \"Yes\" ? 2 : 1)} /^ {8}[^ ]+/{if(found) {exit}; scale=1} END{printf \"%d %d %d\\n\", width, height, scale}'")
set x to ((width / 2) / scale)
set y to ((height / 2) / scale)

#get the product name using a bash script
set {product_name} to words of (do shell script "printf \"%s\", $PRODUCT_NAME")
set background to alias ("Volumes:"&product_name&":.background:some_image.png")

tell application "Finder"
    tell disk product_name
        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 {x, y, (x + 479), (y + 383)}
        set theViewOptions to the icon view options of container window
        set arrangement of theViewOptions to not arranged
        set icon size of theViewOptions to 128
        set background picture of theViewOptions to background
        set position of item (product_name & ".app") of container window to {100, 225}
        set position of item "Applications" of container window to {375, 225}
        update without registering applications
        close
    end tell
end tell

上述針對我項目的窗口測量的具體測量是由於我的背景圖片和圖標分辨率的大小; 您可能需要為您自己的項目修改這些值。

腳本3(製作最終的磁盤映像腳本):

#!/bin/bash
dir="$TEMP_FILES_DIR/disk"
cp "$PROJECT_DIR/$PROJECT_NAME/some_other_image.png" "$dir/"

#unmount the temp image file, then convert it to final image file
sync
sync
hdiutil detach /Volumes/$PRODUCT_NAME
rm -f "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.dmg"
hdiutil convert "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.temp.dmg" -format UDZO -imagekey zlib-level=9 -o "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.dmg"
rm -f "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.temp.dmg"

#Change the icon of the image file
sips -i "$dir/some_other_image.png"
DeRez -only icns "$dir/some_other_image.png" > "$dir/tmpicns.rsrc"
Rez -append "$dir/tmpicns.rsrc" -o "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.dmg"
SetFile -a C "$BUILT_PRODUCTS_DIR/$PRODUCT_NAME.dmg"

rm -rf "$dir"

確保您使用的圖像文件位於$ PROJECT_DIR / $ PROJECT_NAME /目錄中!





dmg