Come posso creare un DMG dall’aspetto gradevole per Mac OS X utilizzando strumenti da riga di comando?

Devo creare un buon programma di installazione per un’applicazione Mac. Voglio che sia un’immagine del disco (DMG), con una dimensione, un layout e un’immagine di sfondo predefiniti.

Ho bisogno di farlo a livello di programmazione in uno script, per essere integrato in un sistema di build esistente (più di un sistema di pacchetti in realtà, dal momento che crea solo installer.) Le build sono fatte separatamente).

Ho già eseguito la creazione DMG utilizzando “hdiutil”, ciò che non ho ancora scoperto è come creare un layout di icone e specificare una bitmap di sfondo.

Dopo molte ricerche, ho trovato questa risposta, e con questo la sto mettendo qui come risposta alla mia domanda, per riferimento:

  1. Assicurati che “Abilita accesso per dispositivi di assistenza” sia selezionato in Preferenze di Sistema >> Accesso Universale. È necessario che AppleScript funzioni. Potrebbe essere necessario riavviare dopo questa modifica (altrimenti non funziona su Mac OS X Server 10.4).

  2. Creare un DMG R / W. Deve essere più grande del risultato. In questo esempio, la variabile bash “size” contiene la dimensione in Kb e il contenuto della cartella nella variabile bash “source” verrà copiato nel DMG:

    hdiutil create -srcfolder "${source}" -volname "${title}" -fs HFS+ \ -fsargs "-cc=64,a=16,e=16" -format UDRW -size ${size}k pack.temp.dmg 
  3. Montare l’immagine del disco e memorizzare il nome del dispositivo (si potrebbe voler utilizzare il sonno per alcuni secondi dopo questa operazione):

     device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \ egrep '^/dev/' | sed 1q | awk '{print $1}') 
  4. Memorizza l’immagine di sfondo (in formato PNG) in una cartella denominata “.background” nel DMG e memorizza il suo nome nella variabile “backgroundPictureName”.

  5. Usa AppleScript per impostare gli stili visivi (il nome di .app deve essere nella variabile bash “applicationName”, usa le variabili per le altre proprietà come necessario):

     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 
  6. Finalizza il DMG impostando le autorizzazioni correttamente, comprimendolo e rilasciandolo:

     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 

Su Snow Leopard, il suddetto script non imposterà correttamente la posizione dell’icona: sembra un bug di Snow Leopard. Una soluzione è chiamare semplicemente chiudi / apri dopo aver impostato le icone, ad esempio:

 .. set position of item "'${applicationName}'" of container window to {100, 100} set position of item "Applications" of container window to {375, 100} close open 

C’è un piccolo script Bash chiamato create-dmg che crea DMG fantasiosi con sfondi personalizzati, posizionamento di icone personalizzate e nome del volume.

L’ho costruito molti anni fa per la compagnia che gestivo all’epoca; sopravvive sul contributo di altre persone da allora, e secondo come riferito funziona bene.

C’è anche node-appdmg che sembra uno sforzo più moderno e attivo basato su Node.js; controllalo pure.

Non andare lì. Come sviluppatore Mac a lungo termine, posso assicurarti che nessuna soluzione funziona davvero bene. Ho provato così tante soluzioni, ma non sono tutte troppo buone. Penso che il problema sia che Apple non documenta realmente il formato dei metadati per i dati necessari.

Ecco come lo sto facendo da molto tempo, con molto successo:

  1. Crea un nuovo DMG, scrivibile (!), Abbastanza grande da contenere il binario previsto e file extra come readme (sparse potrebbe funzionare).

  2. Montare il DMG e dargli un layout manualmente in Finder o con qualsiasi strumento adatto a farlo (vedi il link FileStorm in basso per un buon strumento). L’immagine di sfondo è solitamente un’immagine che abbiamo inserito in una cartella nascosta (“.qualcosa”) sul DMG. Metti una copia della tua app lì (qualsiasi versione, anche quella obsoleta lo farà). Copia altri file (alias, readme, ecc.) Che vuoi lì, ancora una volta, le versioni obsolete andranno bene. Assicurati che le icone abbiano le giuste dimensioni e posizioni (IOW, imposti il ​​DMG nel modo in cui vuoi che sia).

  3. Smontare di nuovo il DMG, tutte le impostazioni dovrebbero essere salvate ora.

  4. Scrivi uno script DMG creato, che funzioni come segue:

    • Copia il DMG, quindi l’originale non viene mai più toccato.
    • Monta la copia.
    • Sostituisce tutti i file con quelli più aggiornati (ad esempio l’ultima app dopo la compilazione). Puoi semplicemente usare mv o idem per quello sulla riga di comando. Nota, quando si sostituisce un file come quello, l’icona rimarrà la stessa, la posizione rimarrà la stessa, tutto tranne il contenuto del file (o della directory) rimane lo stesso (almeno con idem, che usiamo di solito per quell’attività) . Ovviamente puoi anche sostituire l’immagine di sfondo con un’altra (assicurati che abbia le stesse dimensioni).
    • Dopo aver sostituito i file, fai di nuovo lo sassembly della copia DMG dallo script.
    • Infine chiama hdiutil per convertire il file scrivibile, in un DMG compresso (e non scrivibile).

Questo metodo potrebbe non sembrare ottimale, ma credimi, funziona davvero bene nella pratica. Puoi mettere il DMG originale (modello DMG) anche sotto controllo di versione (ad es. SVN), quindi se lo cambi / distruggi accidentalmente, puoi semplicemente tornare a una revisione in cui era ancora a posto. Puoi aggiungere il modello DMG al tuo progetto Xcode, insieme a tutti gli altri file che appartengono al DMG (readme, file URL, immagine di sfondo), tutti sotto controllo di versione e quindi creare un target (ad es. Un target esterno denominato “Crea DMG”) e lì esegui lo script DMG di sopra e aggiungi il tuo vecchio target principale come target dipendente. Puoi accedere ai file nell’albero Xcode utilizzando $ {SRCROOT} nello script (è sempre la radice di origine del tuo prodotto) e puoi accedere ai prodotti build utilizzando $ {BUILT_PRODUCTS_DIR} (è sempre la directory in cui Xcode crea i risultati di compilazione) .

Risultato: in realtà Xcode può produrre il DMG alla fine della compilazione. Un DMG pronto per il rilascio. Non solo è ansible creare un DMG di resase abbastanza facile in questo modo, è ansible farlo in un processo automatizzato (su un server headless, se lo si desidera), utilizzando xcodebuild dalla riga di comando (build notturni automatizzati, ad esempio).

Per quanto riguarda il layout iniziale del modello, FileStorm è un ottimo strumento per farlo. È commerciale, ma molto potente e facile da usare. La versione normale è inferiore a $ 20, quindi è davvero conveniente. Forse uno può automatizzare FileStorm per creare un DMG (ad esempio tramite AppleScript), non l’ha mai provato, ma una volta trovato il modello perfetto DMG, è davvero facile aggiornarlo per ogni versione.

Aggiornando questa domanda fornendo questa risposta.

appdmg è un programma a linea di comando open source semplice, facile da usare che crea file dmg da una semplice specifica di json. Dai un’occhiata al readme sul sito ufficiale:

https://github.com/LinusU/node-appdmg

Esempio veloce:

  1. Installa appdmg

     npm install -g appdmg 
  2. Scrivi un file 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. Eseguire il programma

     appdmg spec.json test.dmg 

(disclaimer: sono il creatore di appdmg)

Per quelli di voi che sono interessati a questo argomento, dovrei menzionare come creo il DMG:

 hdiutil create XXX.dmg -volname "YYY" -fs HFS+ -srcfolder "ZZZ" 

dove

 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 

La mia app, DropDMG , è un modo semplice per creare immagini disco con immagini di sfondo, layout di icone, icone di volume personalizzato e accordi di licenza software. Può essere controllato da un sistema di build tramite lo strumento da riga di comando “dropdmg” o AppleScript. Se lo si desidera, i file RTF dell’immagine e della licenza possono essere memorizzati nel sistema di controllo della versione.

Ho trovato questa fantastica app per mac per automatizzare il processo – http://www.araelium.com/dmgcanvas/ devi dare un’occhiata se stai creando il programma di installazione dmg per la tua app mac

Se si desidera impostare l’icona del volume personalizzato, utilizzare il comando riportato di seguito

 /*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 //.VolumeIcon.icns 

Ora crea dmg di lettura / scrittura

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

I file .DS_Store memorizzano le impostazioni di Windows in Mac. Le impostazioni di Windows includono il layout delle icone, lo sfondo della finestra, la dimensione della finestra, ecc. Il file .DS_Store è necessario per creare la finestra per le immagini montate per preservare la disposizione dei file e lo sfondo di Windows.

Una volta creato il file .DS_Store, è sufficiente copiarlo sul programma di installazione (DMG) creato.

Ho anche bisogno di usare l’approccio a riga di comando per eseguire la creazione di pacchetti e dmg “a livello di programmazione in uno script”. La migliore risposta che ho trovato finora è dal framework di costruzione del progetto Adium (Vedi R1). È disponibile uno script personalizzato (AdiumApplescriptRunner) che consente di evitare l’interazione con la GUI di Windows Server OSX. L’approccio “osascript applescript.scpt” richiede di accedere come builder ed eseguire la creazione di dmg da una sessione vt100 della riga di comando.

Il sistema di gestione dei pacchetti OSX non è così avanzato rispetto ad altri Unixen che possono svolgere questa attività facilmente e sistematicamente.

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

Finalmente ho ottenuto questo lavoro nel mio progetto (che capita di essere in Xcode). L’aggiunta di questi 3 script alla fase di creazione creerà automaticamente un’immagine disco per il tuo prodotto che è bella e ordinata. Tutto quello che devi fare è build il tuo progetto e il DMG ti aspetterà nella cartella dei tuoi prodotti.

Script 1 (Crea immagine disco temp):

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

Script 2 (Imposta script proprietà finestra):

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

La misurazione di cui sopra per la finestra funziona per il mio progetto, in particolare a causa delle dimensioni della mia immagine di sfondo e della risoluzione dell’icona; potrebbe essere necessario modificare questi valori per il proprio progetto.

Script 3 (Crea script immagine disco finale):

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

Assicurati che i file di immagine che stai utilizzando siano nella directory $ PROJECT_DIR / $ PROJECT_NAME /!

Per creare un DMG bello, ora puoi semplicemente utilizzare alcune fonti aperte ben scritte:

  • creare-dmg
  • node-appdmg
  • dmgbuild

Queste risposte sono troppo complicate e i tempi sono cambiati. I seguenti lavori su 10.9 vanno bene, i permessi sono corretti e sembra bello.

Creare un DMG di sola lettura da una directory

 #!/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 "-cc=64,a=16,e=16" \ -format UDZO -imagekey zlib-level=9 "$DMG" if [ -n "$CODESIGN_IDENTITY" ]; then codesign -s "$CODESIGN_IDENTITY" -v "$DMG" fi 

Crea DMG di sola lettura con un’icona (tipo .icns)

 #!/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 "-cc=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 

Se qualcos’altro deve accadere, la cosa più semplice è fare una copia temporanea di SRC_DIR e applicare le modifiche a questo prima di creare un DMG.

Ho appena scritto una nuova (amichevole) utility da riga di comando per farlo. Non si basa su Finder / AppleScript, né su alcuna (deprecata) API Alias ​​Manager, ed è facile da configurare e utilizzare.

Ad ogni modo, chiunque sia interessato può trovarlo su PyPi ; la documentazione è disponibile su Leggi i documenti .