Come posso creare un DMG di bell'aspetto per Mac OS X utilizzando gli strumenti da riga di comando?

StackOverflow https://stackoverflow.com/questions/96882

Domanda

Devo creare un simpatico programma di installazione per un'applicazione Mac.Voglio che sia un'immagine disco (DMG), con dimensioni, layout e immagine di sfondo predefiniti.

Devo farlo a livello di programmazione in uno script, per essere integrato in un sistema di build esistente (più di un sistema di pacchetto in realtà, poiché crea solo programmi di installazione.Le costruzioni vengono eseguite separatamente).

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

È stato utile?

Soluzione

Dopo molte ricerche, ho trovato questa risposta e la inserisco 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 affinché AppleScript funzioni.Potrebbe essere necessario riavviare dopo questa modifica (altrimenti non funziona su Mac OS X Server 10.4).

  2. Crea un DAN 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 "-c c=64,a=16,e=16" -format UDRW -size ${size}k pack.temp.dmg
    
  3. Monta l'immagine del disco e memorizza il nome del dispositivo (potresti voler utilizzare la sospensione 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 chiamata ". background" nel DMG e memorizza il suo nome nella variabile " backgroundPictureName ".

  5. Utilizza AppleScript per impostare gli stili visivi (il nome di .app deve essere nella variabile bash "applicationName", utilizza le variabili per le altre proprietà secondo necessità):

    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 correttamente i permessi, 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, lo script Apple riportato sopra non imposterà correttamente la posizione dell'icona: sembra che si tratti di un bug di Snow Leopard.Una soluzione alternativa è semplicemente chiamare chiudi/apri dopo aver impostato le icone, ovvero:

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

Altri suggerimenti

C'è un piccolo script Bash chiamato crea-dmg che crea DMG fantasiosi con sfondi personalizzati, posizionamento delle icone personalizzato e nome del volume.

L'ho costruito molti anni fa per l'azienda che gestivo all'epoca;da allora sopravvive grazie al contributo di altre persone e, secondo quanto riferito, funziona bene.

C'è anche nodo-appdmg che sembra uno sforzo più moderno e attivo basato su Node.js;dai un'occhiata anche tu.

Non andare lì.Come sviluppatore Mac di lunga data, posso assicurarti che nessuna soluzione funziona davvero bene.Ho provato tante soluzioni, ma non tutte sono 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 i file binari e extra previsti come readme (sparso potrebbe funzionare).

  2. Monta il DMG e assegnagli un layout manualmente nel Finder o con qualsiasi strumento adatto a te per farlo (vedi il collegamento FileStorm in basso per un buon strumento).L'immagine di sfondo è solitamente un'immagine che inseriamo in una cartella nascosta (".something") sul DMG.Metti lì una copia della tua app (va bene qualsiasi versione, anche quella obsoleta).Copia altri file (alias, readme, ecc.) che desideri lì, ancora una volta, le versioni obsolete andranno benissimo.Assicurati che le icone abbiano le dimensioni e le posizioni corrette (IOW, disponi il DMG nel modo desiderato).

  3. Smonta nuovamente il DMG, tutte le impostazioni dovrebbero ormai essere memorizzate.

  4. Scrivi uno script di creazione DMG, che funziona come segue:

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

Questo metodo potrebbe non sembrare ottimale, ma credetemi, nella pratica funziona davvero bene.Puoi mettere il DMG originale (modello DMG) anche sotto il controllo della versione (ad es.SVN), quindi se accidentalmente lo modifichi/distruggi, 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 il controllo della versione e quindi creare un target (ad es.target esterno denominato "Crea DMG") ed eseguire lo script DMG di cui sopra e aggiungere il 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 di compilazione 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 build.Un DAN pronto per essere rilasciato.Non solo puoi creare un DMG di rilascio abbastanza semplice in questo modo, ma puoi effettivamente farlo in un processo automatizzato (su un server headless, se lo desideri), utilizzando xcodebuild dalla riga di comando (ad esempio build notturne automatizzate).

Per quanto riguarda il layout iniziale del modello, FileStorm è un buon strumento per farlo.È commerciale, ma molto potente e facile da usare.La versione normale costa meno di $ 20, quindi è davvero conveniente.Forse si può automatizzare FileStorm per creare un DMG (ad es.tramite AppleScript), non l'ho mai provato, ma una volta trovato il modello DMG perfetto, è davvero facile aggiornarlo per ogni versione.

Aggiornare questa domanda fornendo questa risposta.

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

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

Esempio rapido:

  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 applicazione, DropDMG, è un modo semplice per creare immagini disco con immagini di sfondo, layout di icone, icone di volume personalizzate e contratti di licenza software.Può essere controllato da un sistema di compilazione tramite lo strumento da riga di comando "dropdmg" o AppleScript.Se lo si desidera, i file RTF di immagine e licenza possono essere archiviati 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 desideri impostare l'icona del volume personalizzato, utilizza il comando seguente

/*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

Ora crea leggi/scrivi dmg

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

Per creare un DMG dall'aspetto gradevole, ora puoi semplicemente utilizzare alcuni open source ben scritti:

I file .DS_Store memorizzano le impostazioni di Windows nel Mac.Le impostazioni di Windows includono la disposizione 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 della finestra.

Una volta creato il file .DS_Store, puoi semplicemente copiarlo nel programma di installazione creato (DMG).

Ho anche bisogno di utilizzare l'approccio da riga di comando per eseguire il packaging e la creazione di dmg "a livello di codice in uno script".La migliore risposta che ho trovato finora proviene dal framework di costruzione del rilascio del progetto Adium (vedi R1).È disponibile uno script personalizzato (AdiumApplescriptRunner) per consentire di evitare l'interazione con la GUI di OSX WindowsServer.L'approccio "osascript applescript.scpt" richiede l'accesso come builder ed eseguire la creazione 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 questo compito in modo semplice e sistematico.

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

Finalmente sono riuscito a farlo funzionare nel mio progetto (che sembra essere in Xcode).L'aggiunta di questi 3 script alla fase di creazione creerà automaticamente un'immagine disco per il tuo prodotto che sia bella e ordinata.Tutto quello che devi fare è costruire il tuo progetto e il DMG ti aspetterà nella cartella dei prodotti.

Script 1 (Crea immagine disco temporaneo):

#!/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 (Script Imposta 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 sopra per la finestra funziona per il mio progetto in particolare a causa delle dimensioni dell'immagine di sfondo e della risoluzione delle icone;potrebbe essere necessario modificare questi valori per il tuo 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 immagine che stai utilizzando siano nella directory $PROJECT_DIR/$PROJECT_NAME/!

Queste risposte sono troppo complicate e i tempi sono cambiati.Quanto segue funziona bene su 10.9, le autorizzazioni sono corrette e sembra carino.

Crea 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 "-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

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 "-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

Se è necessario che accada qualcos'altro, la cosa più semplice è creare una copia temporanea di SRC_DIR e applicarvi le modifiche prima di creare un DMG.

Ho appena scritto una nuova (amichevole) utilità da riga di comando per farlo.Non si basa su Finder/AppleScript o su nessuna delle API Alias ​​Manager (deprecate) ed è facile da configurare e utilizzare.

Comunque chiunque sia interessato può farlo trovalo su PyPi;la documentazione è disponibile su Leggi i documenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top