Як створити красивий DMG для Mac OS X за допомогою інструментів командного рядка?


212

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

Мені потрібно це робити програмно за сценарієм, щоб бути інтегрованим у існуючу систему збірки (справді більше системи пакетів, оскільки вона створює лише інсталятори. Збірки виконуються окремо).

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


1
Хіба це не щось для запитання різних?
Ленар Хойт

Відповіді:


199

Після безлічі досліджень я придумав цю відповідь, і я викладаю її тут як відповідь на моє власне питання, для довідки:

  1. Переконайтеся, що "Увімкнути доступ для допоміжних пристроїв" встановлено в розділі Налаштування системи >> Універсальний доступ. Це потрібно, щоб AppleScript працював. Можливо, вам доведеться перезавантажити після цієї зміни (вона не працює інакше на Mac OS X Server 10.4).

  2. Створіть R / W DMG. Він повинен бути більшим, ніж буде результат. У цьому прикладі змінна bash "size" містить розмір у Kb, а вміст папки у змінній 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

1
Відмінно. Два питання з цього приводу: 1. Ви рекомендуєте sleepпісля нанесення зображення. Як довго? Чи не можна детерміновано дочекатися завершення процесу? Те саме для delay 5вашого AppleScript. Я завжди остерігаюся таких довільних періодів очікування, маючи з ними дуже поганий досвід. 2. На кроці 6 ви дзвоните syncдвічі - чому?
Конрад Рудольф

Я не знайшов жодного способу детерміновано дочекатися завершення команди "оновлення без реєстрації програм". Я не впевнений, що після "прив’язки hdiutil" потрібен сон, вам доведеться перевірити документацію (man hdiutil). Синхронізацію потрібно викликати лише один раз, я роблю це два рази за старою звичкою з старих добрих днів SunOS.
Людвіг А. Норін

1
Це дозволяє яблучному сценарію імітувати введення миші та клавіатури та купу інших речей.
Людвіг А. Норін

1
Якщо сценарій зависає, поки він не вичерпається в рядку "оновлення без реєстрації додатків", то крок 1 не був зроблений (або його не скасовано). Я щойно з’ясував це важким шляхом.
Джей Мейнард K5ZC

Я думаю, що я виявив невеликий збій - в AppleScript є викид, який робиться перед тим, як спробувати запустити chmod. chmod вийде з ладу, тому що диск виймається.
Трейказ

56

Існує невеликий сценарій Bash під назвою create-dmg, який створює фантазійні DMG з власними фонами, спеціальним розташуванням піктограм та назвою гучності.

Я будував його багато років тому для компанії, якою я керував у той час; з тих пір він виживає на внеску інших людей і, як повідомляється, працює добре.

Є також node-appdmg, який виглядає як більш сучасний та активний зусилля на основі Node.js; перевірити це також.


7
Посилання на ваш скрипт bash порушено. Чи можете ви помістити його в gistub.com? Дякую
dquimper

create-dmg НЕ позиціонує піктограму добре. Якщо вам потрібна ця функція, не використовуйте її.
laike9m

1
@ laike9m Пройшло більше 5 років, як я востаннє торкнувся цього. Я дійсно не вважаю DMG найкращим способом розповсюдження програмного забезпечення Mac. Тож це виживає на внесках інших людей - сподіваємось, хтось теж з’ясує проблему з іконами.
Андрій Таранцов

3
@ Zmey Ну як користувач, я віддаю перевагу поштових файлів на сьогоднішній день. Бонусні бали за автоматичне копіювання, /Applicationsякщо програма виявить, що вона працює ~/Downloads. Дивіться також цю стару статтю Джона Грубера .
Андрій Таранцов


37

Не їдь туди. Як довгостроковий розробник Mac, можу запевнити, жодне рішення насправді не працює добре. Я спробував так багато рішень, але всі вони не надто хороші. Я думаю, що проблема полягає в тому, що Apple насправді не документує формат метаданих для необхідних даних.

Ось як я це роблю вже давно, дуже успішно:

  1. Створіть новий DMG, доступний для запису (!), Достатній для розміщення очікуваних бінарних та додаткових файлів, таких як readme (рідко може працювати).

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

  3. Знову відключіть DMG, усі налаштування повинні зберігатися на даний момент.

  4. Напишіть сценарій створення DMG, який працює наступним чином:

    • Він копіює DMG, тому оригінал більше не торкається.
    • На ньому монтується копія.
    • Він замінює всі файли найсучаснішими (наприклад, найновішою програмою після збирання). Ви можете просто використовувати mv або ditto для цього в командному рядку. Зауважте, що коли ви замінюєте такий файл, піктограма залишатиметься однаковою, позиція залишатиметься такою ж, все, окрім вмісту файлу (або каталогу), залишатиметься таким же (принаймні, з 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, оновити його дійсно легко для кожного випуску.


3
Я вже відкинув ідею зробити це таким чином з кількох причин. Ось два з них: вміст інсталяторів буде залежати від продукту, і ми хочемо покладатися лише на програмне забезпечення, встановлене на машинах упаковки та сценаріїв - єдиний, мінімальний, ручний режим додавання нових продуктів.
Людвіг А. Норін

Це той самий сценарій, що і у нас. У нас більше десятка продуктів; кожен має абсолютно інший DMG. Створення одного шаблону DMG на продукт - це лише разове завдання і займе у вас пару хвилин. А що ви маєте на увазі під "інсталятором"? Пакети встановлення PKG / MPKG?
Mecki

Це не той самий сценарій. Ми додаємо продукти часто, з коротким повідомленням. Мінімальна ручна процедура означає виконання сценарію, даючи назву продукту та кілька інших атрибутів. Крім цього є причини, які змусили нас прийняти рішення не використовувати таке рішення.
Людвіг А. Норін

Ми відокремили процес упаковки від процесу збирання, оскільки це робиться різними людьми в різний час. Процес упаковки створює інсталятори для Windows, Windows CE, Symbian, AIX, Linux і Solaris.
Людвіг А. Норін

Ви, ймовірно, переглядаєте hdiutil, а не hdutil.
Іван Вучиця

25

Актуалізація цього питання шляхом надання відповіді.

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)


3
простий і ефективний. Єдиний мінус полягає в тому, що він вимагає встановити npm
Джек Джеймс

@Creator: чи можете ви зробити це заздалегідь таким, як ця пропозиція GUI, не потребуючи перетягування? s.sudre.free.fr/Software/Packages/about.html

Якщо файл .app не в тій самій папці, що і файл json, це не працює, він дає помилку "файл не знайдено", коли ви вказуєте відносний шлях у "шляху"
Joey

@Joey, чи можете ви відкрити проблему у сховищі Github, якщо вона не працює для вас?
Linus Unnebäck

@Joey: Не потрібно знаходитись в одній папці, у мене фон, додаток все різним шляхом, просто пройдіть відносні шляхи, як ../../../ABC
Anoop

22

Для тих, хто цікавиться цією темою, я повинен зазначити, як я створюю 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

1
Це добре, але це не відповідає реальній потребі (фонове зображення, розміщення елементів у папці тощо)
Том Богл,

створив DMG, але знову мені доведеться запустити свій скрипт (.sh) за допомогою CMD, мені потрібно його автоматично запустити після створення DMG
SANTOSH

13

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


3
У моєї команди це працює красиво і автоматично на сервері збірки Дженкінс CI, разом із фоном, перетягніть на Псевдонім програм. Бігайте, не ходіть, до DropDMG для створення зображень на диску.
Пол Коллінз

Хороший додаток, я збираюся придбати його після закінчення терміну пробного періоду.
kilik52

Виглядає приємно, але, схоже, немає можливості змінити розмір вікна.
аві

@avi DropDMG автоматично розміщує вікно до фонового зображення, яке ви встановили (або вставте у це зображення за бажанням).
Майкл Цай

Щиро дякую! Чи можна змінити розмір без фонового зображення?
avi

6

Я знайшов цей чудовий додаток mac для автоматизації процесу - http://www.araelium.com/dmgcanvas/ ви повинні мати погляд, якщо ви створюєте інсталятор dmg для свого додатка mac


1
Зауважте, що це не безкоштовна програма, тому вона не підходить для багатьох середовищ.
Джей Мейнард K5ZC

5

Для створення приємного вигляду DMG тепер ви можете просто використовувати кілька добре написаних відкритих джерел:


Можливо, вони його перенесли. Ви можете використовувати create-dmg та node-appdmg. Я використовую create-dmg. Це добре.
Anni S

@ PamelaCook-LightBeCorp Якщо ви все ще зацікавлені. Посилання на dmgbuild було виправлено.
SubOptimal

4

Якщо ви хочете встановити спеціальну піктограму гучності, скористайтеся командою нижче

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

Чи можете ви пояснити, що тут означає "ваш шлях"? Чи можу я використовувати який-небудь файл значків на диску, а SetFile скопіював би його, чи мені потрібно використовувати файл, що знаходиться всередині .dmg? У мене є лише один Mac, тому важко перевірити, чи буде робота на інших машинах.
Мілан Бабушков

"ваш шлях" - це ім'я DMG. (/ Томи / dmgName)
Параг Бафна

Ви повинні скопіювати файл icns. cp "/Volumes/customIcon.icns" "/Volumes/dmgName/.VolumeIcon.icns"
Параг Бафна

4

Нарешті я отримав це, працюючи у власному проекті (який трапляється у 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 /!


Це створює зображення порожнього диска в моєму проекті. Будь-яка пропозиція.
ManiaChamp

Частина сценарію оболонки працює лише, але як я можу додати сценарій Apple із сценарієм Shell в RunScript під стадією збірки, вона відображає помилку, кожне повідомлення сценарію яблука є символом не знайдено.
ManiaChamp

2

.DS_Store файли зберігають налаштування Windows на Mac. Параметри Windows включають макет піктограм, фон вікна, розмір вікна тощо. Файл .DS_Store потрібен для створення вікна для змонтованих зображень для збереження розташування файлів та фону вікна.

Після створення файлу .DS_Store ви можете просто скопіювати його у створений інсталятор (DMG).


Але спочатку додайте фонове зображення до dmg, назвавши його чимось на зразок .background.png, а потім використовуючи Cmd-J, щоб додати це (!) Зображення на задній план.
Gijs

2

Мені також потрібно використовувати підхід командного рядка, щоб зробити упаковку та створення dmg "програмно в сценарії". Найкраща відповідь, яку я знайшов поки що, - це проект Adium «Випуск будівельних рам (див. R1). Існує спеціальний сценарій (AdiumApplescriptRunner), який дозволяє вам уникнути взаємодії з графічним інтерфейсом WindowsX Server OSS. Підхід "osascript applescript.scpt" вимагає від вас увійти як конструктор і запустити створення dmg з сеансу командного рядка vt100.

Система управління пакетами OSX не настільки розвинена в порівнянні з іншими Unixen, що може виконати це завдання легко і систематично.

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


2

Я щойно написав нову (дружню) утиліту командного рядка для цього. Він не покладається на Finder / AppleScript або будь-який із (застарілих) API Alias ​​Manager, і його легко налаштувати та використовувати.

У будь-якому разі, кожен, хто зацікавлений, може знайти його на PyPi ; Документація доступна на Read The Docs .


1

Ці відповіді занадто складні, і часи змінилися. Наступні роботи на 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.


Ця відповідь не додає нічого до написаного раніше, а також не дає відповіді на початкове запитання (справа не в тому, щоб просто поставити піктограму в dmg або про те, як її підписати; питання полягає в програмному додаванні графіки та значків позиціонування дмг).
Людвіг А. Норін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.