web-dev-qa-db-fra.com

Comment créer un joli DMG pour Mac OS X à l'aide d'outils de ligne de commande?

Je dois créer un programme d'installation Nice pour une application Mac. Je veux que ce soit une image disque (DMG), avec une taille, une mise en page et une image d'arrière-plan prédéfinies.

Je dois le faire par programme dans un script, pour être intégré dans un système de construction existant (plutôt un système de pack, puisqu'il ne crée que des installateurs. Les versions sont réalisées séparément).

La création de DMG est déjà effectuée avec "hdiutil". Ce que je n’ai pas encore appris, c’est comment créer une disposition des icônes et spécifier un bitmap d’arrière-plan.

205
Ludvig A. Norin

Après de nombreuses recherches, j'ai trouvé cette réponse et je la présente ici comme réponse à ma propre question, à titre de référence:

  1. Assurez-vous que l'option "Activer l'accès pour les périphériques d'assistance" est cochée dans Préférences Système >> Accès universel. Il est nécessaire que AppleScript fonctionne. Il se peut que vous deviez redémarrer après cette modification (cela ne fonctionne pas sous Mac OS X Server 10.4).

  2. Créez un DMG R/W. Il doit être plus grand que le résultat sera. Dans cet exemple, la variable bash "taille" contient la taille entre Kb) et le contenu du dossier de la variable "source" bash sera copié dans le fichier 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. Montez l'image disque et stockez le nom du périphérique (vous pouvez utiliser le mode veille pendant quelques secondes après cette opération):

    device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
             egrep '^/dev/' | sed 1q | awk '{print $1}')
    
  4. Stockez l'image d'arrière-plan (au format PNG) dans un dossier appelé ".background" dans le fichier DMG et stockez son nom dans la variable "backgroundPictureName".

  5. Utilisez AppleScript pour définir les styles visuels (le nom du fichier .app doit figurer dans la variable bash "nomApplication", utilisez des variables pour les autres propriétés, le cas échéant):

    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. Finialisez le fichier DMG en définissant correctement les autorisations, en le compressant et en le relâchant:

    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 
    

Sur Snow Leopard, l'applescript ci-dessus ne définira pas correctement la position de l'icône - il semble s'agir d'un bogue Snow Leopard. Une solution consiste simplement à appeler fermer/ouvrir après avoir défini les icônes, à savoir:

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

Il existe un petit script Bash appelé create-dmg qui crée des DMG sophistiqués avec des arrière-plans personnalisés, un positionnement d'icône personnalisé et un nom de volume.

Je l'ai construit il y a plusieurs années pour la société que je dirigeais à l'époque; depuis lors, il survit grâce à la contribution d'autres personnes et fonctionnerait bien.

Il y a aussi node-appdmg qui ressemble à un effort plus moderne et actif basé sur Node.js; vérifiez aussi.

56
Andrey Tarantsov

N'y allez pas. En tant que développeur Mac à long terme, je peux vous assurer qu'aucune solution ne fonctionne vraiment bien. J'ai essayé tellement de solutions, mais elles ne sont pas toutes bonnes. Je pense que le problème est que Apple ne documente pas vraiment le format de métadonnées pour les données nécessaires.

Voici comment je le fais depuis longtemps, avec beaucoup de succès:

  1. Créez un nouveau fichier DMG, inscriptible (!), Suffisamment grand pour contenir les fichiers binaires et supplémentaires attendus, tels que le fichier Lisez-moi (peu de données peuvent fonctionner).

  2. Montez le DMG et attribuez-lui une mise en page manuellement dans le Finder ou avec les outils qui vous conviennent (voir le lien FileStorm en bas pour un bon outil). L'image d'arrière-plan est généralement une image que nous avons placée dans un dossier caché (".quelque chose") sur le fichier DMG. Mettez une copie de votre application là-bas (n'importe quelle version, même périmée, fera l'affaire). Copiez les autres fichiers (alias, readme, etc.) de votre choix, là encore, les versions obsolètes feront l'affaire. Assurez-vous que les icônes ont la bonne taille et la bonne position (IOW, organisez le fichier DMG comme vous le souhaitez).

  3. Démontez à nouveau le DMG, tous les paramètres devraient être stockés maintenant.

  4. Écrivez un script de création DMG, qui fonctionne comme suit:

    • Il copie le fichier DMG, l’original n’est donc plus touché.
    • Il monte la copie.
    • Il remplace tous les fichiers par les fichiers les plus récents (par exemple, la dernière application après la construction). Vous pouvez simplement utiliser mv ou idem pour cela en ligne de commande. Notez que lorsque vous remplacez un fichier comme celui-ci, l'icône reste la même, la position reste la même, tout sauf le contenu du fichier (ou du répertoire) reste la même (au moins avec idem, que nous utilisons habituellement pour cette tâche). . Vous pouvez bien sûr également remplacer l’image d’arrière-plan par une autre (assurez-vous simplement qu’elle a les mêmes dimensions).
    • Après avoir remplacé les fichiers, forcez le script à démonter à nouveau la copie DMG.
    • Enfin, appelez hdiutil pour convertir le fichier inscriptible en un fichier DMG compressé (et non inscriptible).

Cette méthode peut ne pas sembler optimale, mais croyez-moi, cela fonctionne très bien dans la pratique. Vous pouvez placer le modèle DMG d'origine (modèle DMG) même sous contrôle de version (par exemple, SVN). Ainsi, si vous le modifiez/détruisez par inadvertance, vous pouvez simplement revenir à une révision où tout allait bien. Vous pouvez ajouter le modèle DMG à votre projet Xcode, ainsi que tous les autres fichiers appartenant au fichier DMG (fichier readme, fichier URL, image d'arrière-plan), le tout sous contrôle de version, puis créer une cible (par exemple, une cible externe nommée "Créer un fichier DMG"). et exécutez le script DMG ci-dessus et ajoutez votre ancienne cible principale en tant que cible dépendante. Vous pouvez accéder aux fichiers de l'arborescence Xcode en utilisant $ {SRCROOT} dans le script (c'est toujours la racine source de votre produit) et vous pouvez accéder aux produits de construction en utilisant $ {BUILT_PRODUCTS_DIR} (c'est toujours le répertoire dans lequel Xcode crée les résultats de la construction). .

Résultat: en réalité, Xcode peut générer le fichier DMG à la fin de la construction. Un DMG prêt à être publié. Non seulement vous pouvez créer un fichier DMG assez facile de cette manière, vous pouvez également le faire dans un processus automatisé (sur un serveur sans tête si vous le souhaitez), en utilisant xcodebuild à partir de la ligne de commande (constructions nocturnes automatisées, par exemple).

En ce qui concerne la disposition initiale du modèle, FileStorm est un bon outil pour le faire. C'est commercial, mais très puissant et facile à utiliser. La version normale coûte moins de 20 dollars, elle est donc très abordable. On peut peut-être automatiser FileStorm pour créer un fichier DMG (par exemple, via AppleScript), jamais essayé, mais une fois que vous avez trouvé le modèle DMG idéal, il est vraiment facile de le mettre à jour pour chaque version.

37
Mecki

Mise à jour de cette question en fournissant cette réponse.

appdmg est un programme de ligne de commande open source, simple, facile à utiliser, qui crée des fichiers dmg à partir d'une simple spécification Json. Jetez un coup d'œil au readme sur le site officiel:

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

Exemple rapide:

  1. Installer appdmg

    npm install -g appdmg
    
  2. Ecrire un fichier 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. Exécuter de programme

    appdmg spec.json test.dmg
    

(disclaimer. Je suis le créateur de appdmg)

26
Linus Unnebäck

Pour ceux d'entre vous qui s'intéressent à ce sujet, je dois mentionner comment j'ai créé le 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
22
Ludvig A. Norin

Mon application, DropDMG , est un moyen simple de créer des images de disque avec des images d'arrière-plan, des dispositions d'icônes, des icônes de volume personnalisé et des contrats de licence de logiciel. Il peut être contrôlé à partir d'un système de construction via l'outil de ligne de commande "dropdmg" ou AppleScript. Si vous le souhaitez, les fichiers image et licence RTF peuvent être stockés sous votre système de contrôle de version.

14
Michael Tsai

J'ai trouvé cette excellente application pour automatiser le processus - http://www.araelium.com/dmgcanvas/ vous devez jeter un coup d'œil si vous créez un programme d'installation de dmg pour votre application mac

5
Saurabh

Si vous souhaitez définir une icône de volume personnalisé, utilisez la commande ci-dessous.

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

Maintenant, créez des dmg en lecture/écriture

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

Pour créer un joli DMG, vous pouvez maintenant utiliser quelques sources ouvertes bien écrites:

4
Anni S

Les fichiers .DS_Store stockent les paramètres de Windows dans Mac. Les paramètres Windows incluent la disposition des icônes, l'arrière-plan de la fenêtre, la taille de la fenêtre, etc. Le fichier .DS_Store est nécessaire pour créer la fenêtre des images montées afin de préserver la disposition des fichiers et l'arrière-plan de la fenêtre.

Une fois le fichier .DS_Store créé, vous pouvez simplement le copier sur votre installateur créé (DMG).

2
hor10zs

J'ai également besoin d'une approche en ligne de commande pour créer le packaging et la création de dmg "par programmation dans un script". La meilleure réponse que j’ai trouvée jusqu’à présent est tirée du projet Adium 'Release building framework (voir R1). Il existe un script personnalisé (AdiumApplescriptRunner) qui vous permet d’éviter les interactions entre l’interface graphique OSX WindowsServer. L'approche "osascript applescript.scpt" nécessite que vous vous connectiez en tant que générateur et que vous exécutiez la création de dmg à partir d'une session vt100 en ligne de commande.

Le système de gestion de paquets OSX n’est pas aussi avancé par rapport aux autres systèmes Unixen qui peuvent effectuer cette tâche facilement et systématiquement.

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

2
T.J. Yang

J'ai finalement obtenu ce travail dans mon propre projet (qui se trouve être dans Xcode). L'ajout de ces 3 scripts à votre phase de création créera automatiquement une image disque propre et agréable pour votre produit. Tout ce que vous avez à faire est de construire votre projet et le DMG attendra dans votre dossier de produits.

Script 1 (Créer une image de disque temporaire):

#!/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 de définition des propriétés de la fenêtre):

#!/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 mesure ci-dessus pour la fenêtre fonctionne pour mon projet, en raison de la taille de ma taille d'image d'arrière-plan et de la résolution de mon icône; vous devrez peut-être modifier ces valeurs pour votre propre projet.

Script 3 (Créer le script final d'image disque):

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

Assurez-vous que les fichiers image que vous utilisez sont dans le répertoire $ PROJECT_DIR/$ PROJECT_NAME /!

2
P.M.

Je viens d'écrire un nouvel utilitaire (convivial) en ligne de commande pour le faire. Il ne repose pas sur Finder/AppleScript, ni sur aucune des API Alias ​​Manager (dépréciées), et il est facile à configurer et à utiliser.

Quoi qu'il en soit, toute personne intéressée peut trouver sur PyPi ; la documentation est disponible sur Read The Docs .

1
alastair

Ces réponses sont trop compliquées et les temps ont changé. Ce qui suit fonctionne très bien sur 10.9, les permissions sont correctes et ça a l'air sympa.

Créer un fichier DMG en lecture seule à partir d'un répertoire

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

Créer un fichier DMG en lecture seule avec une icône (type .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

Si quelque chose d'autre devait se produire, la chose la plus simple à faire est de créer une copie temporaire de SRC_DIR et de l'appliquer avant de créer un fichier DMG.

1
user246672