Как создать приятный DMG для Mac OS X с помощью инструментов командной строки?

Мне нужно создать хороший установщик для приложения Mac. Я хочу, чтобы это был образ диска (DMG) с предопределенным размером, макетом и фоновым изображением.

Мне нужно сделать это программно в script, чтобы быть интегрированным в существующую систему сборки (больше система пакетов, поскольку она только создает установщиков. Сборки выполняются отдельно).

У меня уже создано создание DMG с помощью "hdiutil", чего я еще не выяснил, как создать макет значка и указать фоновое растровое изображение.

Ответ 1

После долгих исследований я придумал этот ответ, и поэтому я ставлю его здесь как ответ для моего собственного вопроса, для справки:

  • Убедитесь, что "Включить доступ для вспомогательных устройств" отмечен в "Системные настройки" > "Универсальный доступ". Это необходимо для работы AppleScript. Возможно, вам придется перезагрузиться после этого изменения (это не работает в Mac OS X Server 10.4).

  • Создайте R/W DMG. Он должен быть больше, чем результат. В этом примере размер переменной bash "size" содержит размер в Kb, и содержимое папки в "исходной" переменной bash будет скопировано в 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
    
  • Установите образ диска и сохраните имя устройства (вы можете использовать сон в течение нескольких секунд после этой операции):

    device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
             egrep '^/dev/' | sed 1q | awk '{print $1}')
    
  • Сохраните фоновое изображение (в формате PNG) в папке с именем ".background" в DMG и сохраните его имя в переменной "backgroundPictureName".

  • Используйте AppleScript для установки визуальных стилей (имя .app должно быть в переменной bash "имя_приложения", при необходимости используйте переменные для других свойств):

    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
    
  • Завершите работу DMG, установив разрешения правильно, сжимая и освобождая его:

    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 
    

На Snow Leopard вышеупомянутый applescript не будет правильно устанавливать положение значка - кажется, это ошибка Snow Leopard. Одним из способов решения является просто вызвать close/open после установки значков, то есть:

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

Ответ 2

Там немного Bash script, называемый create-dmg, который создает причудливые DMG с настраиваемыми фонами, пользовательским расположением значков и именем тома.

Я построил его много лет назад для компании, в которой я работал в то время; с тех пор он выживает на чужом вкладе и, как сообщается, хорошо работает.

Там также node-appdmg, который выглядит как более современное и активное усилие, основанное на Node.js; проверьте его также.

Ответ 3

Не ходите туда. Будучи разработчиком Mac на длительный срок, я могу заверить вас, что решение действительно не работает. Я пробовал так много решений, но все они не слишком хороши. Я думаю, проблема в том, что Apple не документирует формат метаданных для необходимых данных.

Вот как я делаю это в течение долгого времени, очень успешно:

  • Создайте новый DMG, записываемый (!), достаточно большой, чтобы содержать ожидаемые двоичные и дополнительные файлы, такие как readme (разреженный может работать).

  • Установите DMG и дайте ему макет вручную в Finder или с любыми инструментами, которые вам подходят для этого (см. ссылку FileStorm внизу для хорошего инструмента). Фоновое изображение обычно представляет собой изображение, которое мы помещаем в скрытую папку ( ".something" ) на DMG. Поместите туда копию своего приложения (любая версия, даже устаревшая сделана). Скопируйте другие файлы (псевдонимы, readme и т.д.), Которые вы хотите там, опять же устаревшие версии сделают все в порядке. Убедитесь, что значки имеют правильные размеры и позиции (IOW, макет DMG так, как вы этого хотите).

  • Отключите DMG снова, все настройки должны быть сохранены.

  • Напишите созданный DMG script, который работает следующим образом:

    • Он копирует DMG, поэтому оригинал никогда не трогается снова.
    • Он монтирует копию.
    • Он заменяет все файлы самыми современными (например, последнее приложение после сборки). Вы можете просто использовать mv или ditto для этого в командной строке. Обратите внимание, что при замене такого файла значок останется прежним, позиция останется неизменной, все, кроме содержимого файла (или каталога), останется прежним (по крайней мере, с тем же, что мы обычно используем для этой задачи), Вы можете, конечно, также заменить фоновое изображение на другое (просто убедитесь, что он имеет одинаковые размеры).
    • После замены файлов сделайте script снова отключением копии DMG.
    • Наконец, вызовите hdiutil для преобразования записываемого файла в сжатый (и такой не записываемый) DMG.

Этот метод может показаться не оптимальным, но поверьте мне, он работает на практике. Вы можете поместить оригинальный DMG (шаблон DMG) даже под управлением версиями (например, SVN), поэтому, если вы когда-либо случайно измените/уничтожьте его, вы можете просто вернуться к ревизии, где все еще было в порядке. Вы можете добавить шаблон DMG в свой проект Xcode вместе со всеми другими файлами, принадлежащими DMG (readme, URL файл, фоновое изображение), все под управлением версиями, а затем создать цель (например, внешняя цель с именем "Create DMG" ) и запустите DMG script выше и добавьте старую главную цель в качестве зависимой цели. Вы можете получить доступ к файлам в дереве Xcode с помощью ${SRCROOT} в script (всегда является исходным корнем вашего продукта), и вы можете получить доступ к продуктам сборки с помощью ${BUILT_PRODUCTS_DIR} (всегда это каталог, в котором Xcode создает сборку результаты).

Результат: На самом деле Xcode может создать DMG в конце сборки. DMG, который готов к выпуску. Не только вы можете легко создать relase DMG таким образом, вы можете сделать это в автоматическом процессе (если хотите, на безголовом сервере), используя xcodebuild из командной строки (например, автоматические ночные сборки).

Что касается исходного макета шаблона, FileStorm является хорошим инструментом для этого. Он коммерческий, но очень мощный и простой в использовании. Нормальная версия составляет менее 20 долларов США, поэтому она действительно доступна. Возможно, можно автоматизировать FileStorm для создания DMG (например, через AppleScript), никогда не пробовал это, но как только вы нашли идеальный шаблон DMG, его действительно легко обновить для каждой версии.

Ответ 4

Обновляя этот вопрос, предоставляя этот ответ.

appdmg - простая, простая в использовании программа командной строки с открытым исходным кодом, которая создает dmg файлы из простой json-спецификации. Взгляните на readme на официальном сайте:

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

Быстрый пример:

  • Установить appdmg

    npm install -g appdmg
    
  • Напишите 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" }
      ]
    }
    
  • Запустить программу

    appdmg spec.json test.dmg
    

(отказ от ответственности. Я являюсь создателем appdmg)

Ответ 5

Для тех из вас, кто интересуется этой темой, я должен упомянуть, как я создаю 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

Ответ 6

Мое приложение DropDMG - это простой способ создания образов дисков с фоновыми изображениями, макетами значков, значками тома и программным обеспечением лицензионные соглашения. Его можно контролировать из системы сборки с помощью инструмента командной строки "dropdmg" или AppleScript. При желании файлы RTF изображений и лицензий могут храниться в вашей системе контроля версий.

Ответ 7

Я нашел это отличное приложение для Mac, чтобы автоматизировать процесс - http://www.araelium.com/dmgcanvas/ вы должны посмотреть, создаете ли вы установщик dmg для своего приложения mac

Ответ 8

Если вы хотите установить собственный значок тома, используйте команду

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

Ответ 9

. Файлы DS_Store хранят настройки Windows в Mac. Настройки Windows включают в себя расположение значков, фон окна, размер окна и т.д. Файл .DS_Store необходим для создания окна для смонтированных изображений для сохранения расположения файлов и фона Windows.

После создания файла .DS_Store вы можете просто скопировать его в созданный установщик (DMG).

Ответ 10

Мне также нужно использовать подход командной строки для создания упаковки и создания dmg "программно в script". Лучший ответ, который я нашел до сих пор, - это проект Adium project Release Framework (см. R1). Существует пользовательский script (AdiumApplescriptRunner), который позволяет избежать взаимодействия с графическим интерфейсом OSX WindowsServer. Подход "osascript applescript.scpt" требует, чтобы вы входили в систему как строитель и запускали создание dmg из сеанса командной строки vt100.

Система управления пакетами OSX не настолько продвинута по сравнению с другими Unixen, которые могут легко и систематически выполнять эту задачу.

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

Ответ 11

Для создания красивого DMG теперь вы можете просто использовать хорошо написанные открытые источники:

Ответ 12

Эти ответы слишком сложны и времена изменились. Следующие работы на 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 со значком (тип .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

Если что-то еще должно произойти, проще всего сделать временную копию SRC_DIR и применить к ней изменения до создания DMG.

Ответ 13

Я только что написал новую (дружественную) утилиту командной строки для этого. Он не полагается на Finder/AppleScript или на любой из (устаревших) API-интерфейсов Alias ​​Manager и его легко настраивать и использовать.

В любом случае, любой, кто заинтересован, найдет его на PyPi; документация доступна для чтения документов.

Ответ 14

Наконец-то я получил эту работу в своем собственном проекте (который, случается, в Xcode). Добавление этих 3 скриптов на фазу сборки автоматически создаст образ диска для вашего товара, который будет приятным и аккуратным. Все, что вам нужно сделать - это создать свой проект, и DMG будет ждать в вашей папке с продуктами.

Script 1 (Создать образ диска 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 (Установить свойства окна 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

Вышеуказанное измерение для окна работает для моего проекта специально из-за размера моего фона и разрешения значка; вам может потребоваться изменить эти значения для вашего собственного проекта.

Script 3 (Сделать изображение конечного диска 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"

Убедитесь, что файлы изображений, которые вы используете, находятся в каталоге $PROJECT_DIR/$PROJECT_NAME/!