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

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

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

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

14 ответов


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

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

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

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

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

    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. Finialize в употр путем установки надлежащего разрешения, сжимая и отпуская его:

    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 не будет правильно устанавливать положение значка - кажется, это снег Леопардовый Жук. Одним из обходных путей является просто вызов 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

есть небольшой скрипт Bash под названием create-dmg который строит причудливые DMGs с пользовательскими фонами, пользовательским позиционированием значков и именем Тома.

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

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


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

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

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

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

  3. снова Размонтируйте DMG, все настройки должны быть сохранены.

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

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

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

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

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


обновление этого вопроса путем предоставления этого ответа.

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

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

пример:

  1. установить appdmg

    npm install -g appdmg
    
  2. написать файл 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. запустить программу

    appdmg spec.json test.dmg
    

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


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

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


Я нашел это большое приложение mac для автоматизации процесса -http://www.araelium.com/dmgcanvas/ вы должны иметь взгляд, если вы создаете DMG installer для вашего mac app


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

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

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

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


Мне также нужно использовать подход командной строки для создания упаковки и dmg "программно в скрипте". Лучший ответ, который я нашел до сих пор, - это Adium project' Release building framework (см. R1). Есть специальный скрипт(AdiumApplescriptRunner) позволит вам избежать айфон взаимодействие GUI WindowsServer. "osascript applescript.подход "scpt" требует входа в систему как builder и запуска создания dmg из сеанса командной строки vt100.

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

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


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

Скрипт 1 (Создание Образа Временного Диска):

#!/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 (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=; height=} /Retina/{scale=( == \"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

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

Сценарий 3 (Сделать Окончательный Сценарий Образа Диска):

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


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


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

создайте DMG только для чтения из каталога

#!/bin/sh
# create_dmg Frobulator Frobulator.dmg path/to/frobulator/dir [ 'Your Code Sign Identity' ]
set -e

VOLNAME=""
DMG=""
SRC_DIR=""
CODESIGN_IDENTITY=""

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=""
DMG=""
SRC_DIR=""
ICON_FILE=""
CODESIGN_IDENTITY=""

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}')"
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.


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

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