كيف أقوم بإنشاء DMG جميل المظهر لنظام التشغيل Mac OS X باستخدام أدوات سطر الأوامر؟

StackOverflow https://stackoverflow.com/questions/96882

سؤال

أحتاج إلى إنشاء برنامج تثبيت لطيف لتطبيق Mac.أريدها أن تكون صورة قرص (DMG)، بحجم وتخطيط وصورة خلفية محددة مسبقًا.

أحتاج إلى القيام بذلك برمجيًا في برنامج نصي، ليتم دمجه في نظام بناء موجود (أكثر من نظام حزم حقًا، لأنه يقوم فقط بإنشاء أدوات التثبيت.تتم الإنشاءات بشكل منفصل).

لقد قمت بالفعل بإنشاء DMG باستخدام "hdiutil"، وما لم أكتشفه بعد هو كيفية إنشاء تخطيط رمز وتحديد صورة نقطية للخلفية.

هل كانت مفيدة؟

المحلول

بعد الكثير من البحث، توصلت إلى هذه الإجابة، وأنا أضعها هنا كإجابة لسؤالي الخاص، كمرجع:

  1. تأكد من تحديد "تمكين الوصول للأجهزة المساعدة" في تفضيلات النظام >> الوصول الشامل.إنه مطلوب لكي يعمل AppleScript.قد تضطر إلى إعادة التشغيل بعد هذا التغيير (لا يعمل بخلاف ذلك على نظام التشغيل Mac OS X Server 10.4).

  2. قم بإنشاء R/W DMG.يجب أن يكون أكبر مما ستكون عليه النتيجة.في هذا المثال، يحتوي متغير bash "size" على الحجم بالكيلوبايت وسيتم نسخ محتويات المجلد الموجود في متغير 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
    
  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

نصائح أخرى

هناك نص برمجي صغير يسمى Bash إنشاء-dmg الذي ينشئ DMGs رائعة بخلفيات مخصصة وموضع رمز مخصص واسم وحدة التخزين.

لقد قمت ببنائها منذ سنوات عديدة للشركة التي كنت أديرها في ذلك الوقت؛إنه يعيش على مساهمة الآخرين منذ ذلك الحين، ويقال إنه يعمل بشكل جيد.

هناك ايضا node-appdmg والذي يبدو وكأنه جهد أكثر حداثة ونشاطًا يعتمد على Node.js؛التحقق من ذلك كذلك.

لا تذهب إلى هناك.باعتباري مطور Mac على المدى الطويل، يمكنني أن أؤكد لك أنه لا يوجد حل يعمل بشكل جيد حقًا.لقد جربت الكثير من الحلول، لكنها كلها ليست جيدة جدًا.أعتقد أن المشكلة تكمن في أن شركة Apple لا تقوم بالفعل بتوثيق تنسيق بيانات التعريف للبيانات الضرورية.

وإليك كيف أفعل ذلك لفترة طويلة، بنجاح كبير:

  1. قم بإنشاء DMG جديد، قابل للكتابة (!)، وكبير بما يكفي لاستيعاب الملفات الثنائية والإضافية المتوقعة مثل الملف التمهيدي (قد يعمل القليل منه).

  2. قم بتثبيت DMG ومنحه تخطيطًا يدويًا في Finder أو باستخدام أي أدوات تناسبك للقيام بذلك (راجع رابط FileStorm في الأسفل للحصول على أداة جيدة).عادة ما تكون صورة الخلفية عبارة عن صورة نضعها في مجلد مخفي ("شيء ما") على DMG.ضع نسخة من تطبيقك هناك (أي إصدار، حتى القديم منه سيفي بالغرض).انسخ الملفات الأخرى (الأسماء المستعارة، الملف التمهيدي، وما إلى ذلك) التي تريدها هناك، مرة أخرى، الإصدارات القديمة ستعمل بشكل جيد.تأكد من أن الرموز لها الأحجام والمواضع الصحيحة (IOW، قم بتخطيط DMG بالطريقة التي تريدها).

  3. قم بإلغاء تحميل DMG مرة أخرى، ومن المفترض أن تكون جميع الإعدادات مخزنة الآن.

  4. قم بكتابة برنامج إنشاء DMG النصي، الذي يعمل على النحو التالي:

    • إنه ينسخ DMG، لذلك لا يتم لمس النسخة الأصلية مرة أخرى.
    • فإنه يتصاعد النسخة.
    • فهو يستبدل جميع الملفات بأحدث الملفات (على سبيل المثال.أحدث تطبيق بعد الإنشاء).يمكنك ببساطة استخدام بالسيارات أو كما سبق لذلك على سطر الأوامر.لاحظ أنه عند استبدال ملف مثل هذا، سيبقى الرمز كما هو، وسيظل الموضع كما هو، وسيظل كل شيء ما عدا محتوى الملف (أو الدليل) كما هو (على الأقل كما سبق، والذي نستخدمه عادةً لهذه المهمة) .يمكنك بالطبع أيضًا استبدال صورة الخلفية بصورة أخرى (فقط تأكد من أنها تحتوي على نفس الأبعاد).
    • بعد استبدال الملفات، اجعل البرنامج النصي يقوم بإلغاء تحميل نسخة DMG مرة أخرى.
    • أخيرًا، اتصل بـ hdiutil لتحويل الملف القابل للكتابة إلى DMG مضغوط (وغير قابل للكتابة).

قد لا تبدو هذه الطريقة مثالية، ولكن ثق بي، فهي تعمل بشكل جيد في الممارسة العملية.يمكنك وضع DMG الأصلي (قالب DMG) حتى تحت التحكم في الإصدار (على سبيل المثال.SVN)، لذلك إذا قمت بتغييره/تدميره عن طريق الخطأ، فيمكنك الرجوع إلى المراجعة حيث كان لا يزال على ما يرام.يمكنك إضافة قالب DMG إلى مشروع Xcode الخاص بك، جنبًا إلى جنب مع جميع الملفات الأخرى التي تنتمي إلى DMG (الملف التمهيدي، ملف URL، صورة الخلفية)، وكلها تحت التحكم في الإصدار ثم قم بإنشاء هدف (على سبيل المثال.هدف خارجي يسمى "إنشاء DMG") وقم بتشغيل البرنامج النصي DMG أعلاه وأضف هدفك الرئيسي القديم كهدف تابع.يمكنك الوصول إلى الملفات في شجرة Xcode باستخدام ${SRCROOT} في البرنامج النصي (هو دائمًا الجذر المصدر لمنتجك) ويمكنك الوصول إلى منتجات البناء باستخدام ${BUILT_PRODUCTS_DIR} (هو دائمًا الدليل الذي ينشئ فيه Xcode نتائج البناء) .

نتيجة:في الواقع، يمكن لـ Xcode إنتاج DMG في نهاية البناء.DMG جاهز للإصدار.ليس فقط يمكنك إنشاء DMG إعادة إصدار بسهولة بهذه الطريقة، بل يمكنك فعل ذلك في عملية تلقائية (على خادم بدون رأس إذا أردت)، باستخدام xcodebuild من سطر الأوامر (الإنشاءات الليلية الآلية على سبيل المثال).

فيما يتعلق بالتخطيط الأولي للقالب، عاصفة الملف هي أداة جيدة للقيام بذلك.إنه تجاري ولكنه قوي جدًا وسهل الاستخدام.الإصدار العادي أقل من 20 دولارًا، لذا فهو في المتناول حقًا.ربما يمكن للمرء أتمتة FileStorm لإنشاء DMG (على سبيل المثال.عبر AppleScript)، لم تجرب ذلك مطلقًا، ولكن بمجرد العثور على القالب المثالي DMG، يصبح من السهل جدًا تحديثه لكل إصدار.

تحديث هذا السؤال من خلال تقديم هذه الإجابة.

appdmg هو برنامج سطر أوامر بسيط وسهل الاستخدام ومفتوح المصدر يقوم بإنشاء ملفات dmg من مواصفات json بسيطة.ألق نظرة على الملف التمهيدي على الموقع الرسمي:

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 لتطبيق mac الخاص بك

إذا كنت تريد تعيين رمز حجم مخصص، فاستخدم الأمر أدناه

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

لإنشاء DMG ذو مظهر جميل، يمكنك الآن استخدام بعض المصادر المفتوحة المكتوبة جيدًا:

تقوم ملفات .DS_Store بتخزين إعدادات Windows في نظام Mac.تتضمن إعدادات Windows تخطيط الرموز وخلفية النافذة وحجم النافذة وما إلى ذلك.يلزم وجود ملف .DS_Store لإنشاء نافذة للصور المثبتة للحفاظ على ترتيب الملفات وخلفية Windows.

بمجرد إنشاء ملف .DS_Store، يمكنك فقط نسخه إلى برنامج التثبيت الذي قمت بإنشائه (DMG).

أنا أيضًا بحاجة إلى استخدام نهج سطر الأوامر للقيام بالتعبئة وإنشاء dmg "برمجيًا في برنامج نصي".أفضل إجابة وجدتها حتى الآن هي من إطار عمل إصدار مشروع Adium (انظر R1).يوجد برنامج نصي مخصص (AdiumApplescriptRunner) للسماح لك بتجنب تفاعل OSX WindowsServer GUI.يتطلب أسلوب "osascript applescript.scpt" منك تسجيل الدخول كمنشئ وتشغيل إنشاء dmg من جلسة سطر الأوامر vt100.

نظام إدارة حزم OSX ليس متقدمًا جدًا مقارنة بأنظمة Unixen الأخرى التي يمكنها القيام بهذه المهمة بسهولة وبشكل منهجي.

آر 1: http://hg.adium.im/adium-1.4/file/00d944a3ef16/Release

لقد تمكنت أخيرًا من العمل في مشروعي الخاص (والذي تصادف وجوده في Xcode).ستؤدي إضافة هذه البرامج النصية الثلاثة إلى مرحلة الإنشاء الخاصة بك إلى إنشاء صورة قرص لمنتجك بشكل جميل وأنيق تلقائيًا.كل ما عليك فعله هو إنشاء مشروعك وسيكون 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/!

هذه الإجابات معقدة للغاية وقد تغير الزمن.ما يلي يعمل على الإصدار 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.

لقد قمت للتو بكتابة أداة مساعدة لسطر الأوامر جديدة (سهلة) للقيام بذلك.وهو لا يعتمد على Finder/AppleScript، أو على أي من واجهات برمجة تطبيقات Alias ​​Manager (المهملة)، كما أنه سهل التهيئة والاستخدام.

على أية حال، يمكن لأي شخص مهتم يمكنك العثور عليه على PyPi;التوثيق هو متاح على قراءة المستندات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top