it-swarm.com.de

Wie erstelle ich ein ansprechendes DMG für Mac OS X mithilfe von Befehlszeilentools?

Ich muss ein Nice-Installationsprogramm für eine Mac-Anwendung erstellen. Ich möchte, dass es ein Disk-Image (DMG) mit einer vordefinierten Größe, einem vordefinierten Layout und einem vordefinierten Hintergrundbild ist.

Ich muss dies programmgesteuert in einem Skript tun, um in ein vorhandenes Build-System integriert zu werden (eher ein Pack-System, da es nur Installer erstellt. Die Builds werden separat erstellt).

Ich habe die DMG-Erstellung bereits mit "hdiutil" durchgeführt. Was ich noch nicht herausgefunden habe, ist, wie man ein Icon-Layout erstellt und eine Hintergrund-Bitmap angibt.

205
Ludvig A. Norin

Nach vielen Recherchen habe ich diese Antwort gefunden und hiermit als Antwort auf meine eigene Frage zum Nachschlagen:

  1. Stellen Sie sicher, dass "Zugriff für unterstützende Geräte aktivieren" in den Systemeinstellungen >> Universeller Zugriff aktiviert ist. Es ist erforderlich, damit das AppleScript funktioniert. Möglicherweise müssen Sie nach dieser Änderung einen Neustart durchführen (unter Mac OS X Server 10.4 funktioniert dies nicht).

  2. Erstellen Sie eine R/W-DMG. Es muss größer sein als das Ergebnis sein wird. In diesem Beispiel enthält die Bash-Variable "size" die Größe in Kb= und der Inhalt des Ordners in der Bash-Variablen "source" wird in die DMG kopiert:

    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. Hängen Sie das Disk-Image ein und speichern Sie den Gerätenamen (möglicherweise möchten Sie den Ruhezustand nach diesem Vorgang für einige Sekunden verwenden):

    device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
             egrep '^/dev/' | sed 1q | awk '{print $1}')
    
  4. Speichern Sie das Hintergrundbild (im PNG-Format) in einem Ordner namens ".background" in der DMG und speichern Sie den Namen in der Variablen "backgroundPictureName".

  5. Verwenden Sie AppleScript zum Festlegen der visuellen Stile (der Name von .app muss in der Bash-Variablen "applicationName" enthalten sein; verwenden Sie nach Bedarf Variablen für die anderen Eigenschaften):

    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. Schließen Sie die DMG ab, indem Sie die Berechtigungen richtig festlegen, komprimieren und freigeben:

    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 
    

Auf Snow Leopard wird durch das obige Applescript die Symbolposition nicht korrekt festgelegt - es scheint sich um einen Snow Leopard-Fehler zu handeln. Eine Problemumgehung besteht darin, einfach close/open aufzurufen, nachdem die Symbole festgelegt wurden, d. H .:

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

Es gibt ein kleines Bash-Skript namens create-dmg , das ausgefallene DMGs mit benutzerdefinierten Hintergründen, benutzerdefinierter Symbolpositionierung und Datenträgernamen erstellt.

Ich habe es vor vielen Jahren für die Firma gebaut, die ich damals betrieben habe. es überlebt von dem Beitrag anderer Menschen seitdem und soll gut funktionieren.

Es gibt auch node-appdmg , das wie eine modernere und aktivere Anstrengung aussieht, die auf Node.js basiert; Schau es dir auch an.

56

Geh nicht dorthin. Als langjähriger Mac-Entwickler kann ich Ihnen versichern, dass keine Lösung wirklich gut funktioniert. Ich habe so viele Lösungen ausprobiert, aber sie sind alle nicht zu gut. Ich denke, das Problem ist, dass Apple das Metadatenformat für die erforderlichen Daten nicht wirklich dokumentiert.

So mache ich das schon lange, sehr erfolgreich:

  1. Erstellen Sie eine neue, beschreibbare (!) DMG, die groß genug ist, um die erwarteten Binär- und Extra-Dateien wie Readme-Dateien zu speichern (sparse könnte funktionieren).

  2. Hängen Sie den DMG ein und geben Sie ihm ein Layout manuell im Finder oder mit den für Sie geeigneten Werkzeugen (ein gutes Werkzeug finden Sie im FileStorm-Link unten). Das Hintergrundbild ist normalerweise ein Bild, das wir in einem versteckten Ordner (".something") auf der DMG ablegen. Legen Sie dort eine Kopie Ihrer App ab (jede Version, auch eine veraltete, reicht aus). Kopieren Sie andere Dateien (Aliase, Readme-Dateien usw.), die Sie dort haben möchten. Auch hier reichen veraltete Versionen aus. Stellen Sie sicher, dass die Symbole die richtigen Größen und Positionen haben (IOW, gestalten Sie die DMG so, wie Sie es möchten).

  3. DMG wieder aushängen, alle Einstellungen sollten jetzt gespeichert sein.

  4. Schreiben Sie ein Create-DMG-Skript, das wie folgt funktioniert:

    • Es kopiert das DMG, so dass das Original nie wieder berührt wird.
    • Es hängt die Kopie ein.
    • Es ersetzt alle Dateien durch die aktuellsten (z. B. die neueste App nach dem Erstellen). Sie können dafür einfach mv oder dito in der Befehlszeile verwenden. Beachten Sie, dass beim Ersetzen einer solchen Datei das Symbol unverändert bleibt, die Position unverändert bleibt und der Inhalt der Datei (oder des Verzeichnisses) unverändert bleibt (zumindest bei ditto, das wir normalerweise für diese Aufgabe verwenden). . Sie können das Hintergrundbild natürlich auch durch ein anderes ersetzen (stellen Sie nur sicher, dass es die gleichen Abmessungen hat).
    • Stellen Sie nach dem Ersetzen der Dateien sicher, dass das Skript die DMG-Kopie erneut ausgehängt hat.
    • Rufen Sie schließlich hdiutil auf, um die beschreibbare Datei in eine komprimierte (und nicht beschreibbare) DMG zu konvertieren.

Diese Methode hört sich vielleicht nicht optimal an, aber glauben Sie mir, sie funktioniert in der Praxis wirklich gut. Sie können die ursprüngliche DMG (DMG-Vorlage) auch unter Versionskontrolle stellen (z. B. SVN). Wenn Sie sie also versehentlich ändern/zerstören, können Sie einfach zu einer Revision zurückkehren, bei der sie noch in Ordnung war. Sie können die DMG-Vorlage zusammen mit allen anderen zur DMG gehörenden Dateien (Readme, URL-Datei, Hintergrundbild) unter Versionskontrolle zu Ihrem Xcode-Projekt hinzufügen und anschließend ein Ziel erstellen (z. B. externes Ziel mit dem Namen "Create DMG"). Führen Sie dort das DMG-Skript aus und fügen Sie Ihr altes Hauptziel als abhängiges Ziel hinzu. Sie können mit $ {SRCROOT} im Skript auf Dateien in der Xcode-Struktur zugreifen (ist immer das Quellstammverzeichnis Ihres Produkts) und mit $ {BUILT_PRODUCTS_DIR} auf Build-Produkte zugreifen (ist immer das Verzeichnis, in dem Xcode die Build-Ergebnisse erstellt). .

Ergebnis: Tatsächlich kann Xcode die DMG am Ende des Builds erzeugen. Ein DMG, das zur Veröffentlichung bereit ist. Auf diese Weise können Sie nicht nur ganz einfach ein Relase-DMG erstellen, sondern dies auch in einem automatisierten Prozess (auf einem Headless-Server, wenn Sie möchten), indem Sie xcodebuild über die Befehlszeile verwenden (beispielsweise automatisierte nächtliche Builds).

In Bezug auf das anfängliche Layout der Vorlage ist FileStorm ein gutes Werkzeug dafür. Es ist kommerziell, aber sehr leistungsfähig und einfach zu bedienen. Die normale Version kostet weniger als 20 US-Dollar, ist also wirklich erschwinglich. Möglicherweise kann man FileStorm automatisieren, um eine DMG zu erstellen (z. B. über AppleScript), das habe ich noch nie versucht, aber wenn Sie die perfekte DMG-Vorlage gefunden haben, ist es wirklich einfach, sie für jede Version zu aktualisieren.

37
Mecki

Aktualisieren Sie diese Frage mit dieser Antwort.

appdmg ist ein einfaches, benutzerfreundliches Open-Source-Befehlszeilenprogramm, das aus einer einfachen JSON-Spezifikation DMG-Dateien erstellt. Schauen Sie sich die Readme-Datei auf der offiziellen Website an:

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

Ein kurzes Beispiel:

  1. Installieren Sie appdmg

    npm install -g appdmg
    
  2. Schreiben Sie eine JSON-Datei (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. Programm ausführen

    appdmg spec.json test.dmg
    

(Haftungsausschluss. Ich bin der Schöpfer von appdmg)

26
Linus Unnebäck

Für diejenigen unter Ihnen, die sich für dieses Thema interessieren, sollte ich erwähnen, wie ich die DMG erstelle:

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

woher

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

Meine App DropDMG ist eine einfache Möglichkeit, Datenträgerabbilder mit Hintergrundbildern, Symbollayouts, benutzerdefinierten Volumensymbolen und Softwarelizenzvereinbarungen zu erstellen. Es kann von einem Build-System aus über das Befehlszeilentool "dropdmg" oder AppleScript gesteuert werden. Auf Wunsch können die Bild- und Lizenzdateien RTF unter Ihrem Versionskontrollsystem gespeichert werden.

14
Michael Tsai

Ich fand diese großartige Mac-App, um den Prozess zu automatisieren - http://www.araelium.com/dmgcanvas/ Sie müssen einen Blick darauf werfen, ob Sie ein dmg-Installationsprogramm für Ihre Mac-App erstellen

5
Saurabh

Wenn Sie ein benutzerdefiniertes Lautstärkesymbol festlegen möchten, verwenden Sie den folgenden Befehl

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

Erstellen Sie nun ein Lese-/Schreib-DMG

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

Um eine gut aussehende DMG zu erstellen, können Sie jetzt einige gut geschriebene Open Source-Dateien verwenden:

4
Anni S

.DS_Store-Dateien speichern Windows-Einstellungen in Mac. Zu den Windows-Einstellungen gehören das Layout der Symbole, der Fensterhintergrund, die Größe des Fensters usw. Die Datei .DS_Store wird zum Erstellen des Fensters für bereitgestellte Bilder benötigt, um die Anordnung der Dateien und den Fensterhintergrund beizubehalten.

Sobald Sie eine .DS_Store-Datei erstellt haben, können Sie sie einfach in Ihr erstelltes Installationsprogramm (DMG) kopieren.

2
hor10zs

Ich brauche auch einen Befehlszeilenansatz, um das Packen und Erstellen von DMGs "programmgesteuert in einem Skript" durchzuführen. Die beste Antwort, die ich bisher gefunden habe, stammt aus dem Adium-Projekt 'Release building framework (siehe R1). Es gibt ein benutzerdefiniertes Skript (AdiumApplescriptRunner), mit dem Sie die Interaktion mit der OSX WindowsServer-Benutzeroberfläche vermeiden können. Für den Ansatz "osascript applescript.scpt" müssen Sie sich als Builder anmelden und die DMG-Erstellung über eine Befehlszeilensitzung vt100 ausführen.

Das OSX-Paketverwaltungssystem ist im Vergleich zu anderen Unixen, die diese Aufgabe einfach und systematisch erledigen können, nicht so fortgeschritten.

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

2
T.J. Yang

Ich habe es endlich in meinem eigenen Projekt (das zufällig in Xcode ist) zum Laufen gebracht. Wenn Sie diese drei Skripte zu Ihrer Erstellungsphase hinzufügen, wird automatisch ein ordentliches Disk Image für Ihr Produkt erstellt. Alles, was Sie tun müssen, ist Ihr Projekt zu erstellen und die DMG wird in Ihrem Produktordner warten.

Skript 1 (Temp Disk Image erstellen):

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

Skript 2 (Set Window Properties Script):

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

Die obige Messung für das Fenster funktioniert für mein Projekt speziell aufgrund der Größe meines Hintergrundbilds und der Auflösung der Symbole. Möglicherweise müssen Sie diese Werte für Ihr eigenes Projekt ändern.

Skript 3 (Make Final Disk Image Script):

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

Stellen Sie sicher, dass sich die von Ihnen verwendeten Bilddateien im Verzeichnis $ PROJECT_DIR/$ PROJECT_NAME/befinden!

2
P.M.

Ich habe gerade ein neues (benutzerfreundliches) Befehlszeilenprogramm geschrieben, um dies zu tun. Es basiert nicht auf Finder/AppleScript oder einer der (veralteten) Alias ​​Manager-APIs und ist einfach zu konfigurieren und zu verwenden.

Wie auch immer, jeder, der interessiert ist, kann auf PyPi finden ; Die Dokumentation ist verfügbar unter Read The Docs .

1
alastair

Diese Antworten sind viel zu kompliziert und die Zeiten haben sich geändert. Das Folgende funktioniert mit 10.9 einwandfrei, die Berechtigungen sind korrekt und es sieht gut aus.

Erstellen Sie eine schreibgeschützte DMG aus einem Verzeichnis

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

Schreibgeschütztes DMG mit einem Symbol (Typ .icns) erstellen

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

Wenn etwas anderes passieren muss, ist es am einfachsten, eine temporäre Kopie von SRC_DIR zu erstellen und Änderungen daran vorzunehmen, bevor Sie eine DMG erstellen.

1
user246672