Как создать красивый DMG для Mac OS X с помощью инструментов командной строки? - PullRequest
205 голосов
/ 19 сентября 2008

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

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

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

Ответы [ 14 ]

191 голосов
/ 03 октября 2009

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

  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. Смонтируйте образ диска и сохраните имя устройства (вы можете использовать спящий режим в течение нескольких секунд после этой операции):

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

  5. Используйте AppleScript для установки визуальных стилей (имя .app должно быть в переменной 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. Финализировать 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 приведенный выше яблочный скрипт не будет правильно устанавливать положение иконки - похоже, это ошибка Snow Leopard. Один из обходных путей - просто позвонить закрыть / открыть после установки значков, т.е.

..
set position of item "'${applicationName}'" of container window to {100, 100}
set position of item "Applications" of container window to {375, 100}
close
open
55 голосов
/ 10 марта 2009

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

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

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

37 голосов
/ 19 сентября 2008

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

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

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

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

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

  4. Напишите сценарий создания 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, который готов к выпуску. Таким образом, вы не только можете довольно просто создать релевантный DMG, но вы можете сделать это в автоматизированном процессе (если хотите, на сервере без монитора), используя xcodebuild из командной строки (например, автоматические ночные сборки).

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

25 голосов
/ 23 января 2015

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

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)

22 голосов
/ 19 сентября 2008

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

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

4 голосов
/ 26 августа 2013

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

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

/*to set custom icon attribute*/
SetFile -a C /Volumes/dmgName
3 голосов
/ 20 декабря 2015

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

2 голосов
/ 24 июля 2015

Я, наконец, получил это работать в моем собственном проекте (который происходит в 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

Скрипт 2 (Установить скрипт окна свойств):

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

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

Сценарий 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 /!

...