Pregunta

Necesito crear un buen instalador para una aplicación Mac.Quiero que sea una imagen de disco (DMG), con un tamaño, diseño e imagen de fondo predefinidos.

Necesito hacer esto mediante programación en un script, para integrarlo en un sistema de compilación existente (en realidad, más bien un sistema de paquetes, ya que solo crea instaladores).Las construcciones se realizan por separado).

Ya hice la creación de DMG usando "hdiutil", lo que aún no he descubierto es cómo hacer un diseño de ícono y especificar un mapa de bits de fondo.

¿Fue útil?

Solución

Después de mucha investigación, se me ocurrió esta respuesta y la pongo aquí como respuesta a mi propia pregunta, como referencia:

  1. Asegúrese de que "Habilitar acceso para dispositivos de asistencia" esté marcado en Preferencias del Sistema >> Acceso Universal.Es necesario para que AppleScript funcione.Es posible que tengas que reiniciar después de este cambio (de lo contrario, no funciona en Mac OS X Server 10.4).

  2. Crea un DMG R/W.Debe ser mayor de lo que será el resultado.En este ejemplo, la variable bash "tamaño" contiene el tamaño en Kb y el contenido de la carpeta en la variable bash "fuente" se copiará en el 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. Monte la imagen del disco y almacene el nombre del dispositivo (es posible que desee utilizar la suspensión durante unos segundos después de esta operación):

    device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
             egrep '^/dev/' | sed 1q | awk '{print $1}')
    
  4. Guarde la imagen de fondo (en formato PNG) en una carpeta llamada ".background" en el DMG y almacene su nombre en la variable "backgroundPictureName".

  5. Utilice AppleScript para configurar los estilos visuales (el nombre de .app debe estar en la variable bash "applicationName", utilice variables para las otras propiedades según sea necesario):

    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. Finalice el DMG configurando los permisos correctamente, comprimiéndolo y liberándolo:

    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 
    

En Snow Leopard, el código de Apple anterior no establecerá la posición del icono correctamente; parece ser un error de Snow Leopard.Una solución alternativa es simplemente llamar a cerrar/abrir después de configurar los íconos, es decir:

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

Otros consejos

Hay un pequeño script Bash llamado crear-dmg que crea DMG elegantes con fondos personalizados, posición de ícono personalizada y nombre de volumen.

Lo construí hace muchos años para la empresa que dirigía en ese momento;Desde entonces sobrevive gracias a la contribución de otras personas y, según se informa, funciona bien.

También hay appdmg de nodo que parece un esfuerzo más moderno y activo basado en Node.js;compruébalo también.

No vayas allí.Como desarrollador de Mac desde hace mucho tiempo, puedo asegurarle que ninguna solución funciona realmente bien.Probé muchas soluciones, pero no todas son demasiado buenas.Creo que el problema es que Apple realmente no documenta el formato de metadatos de los datos necesarios.

Así es como lo estoy haciendo desde hace mucho tiempo, con mucho éxito:

  1. Cree un nuevo DMG, que se pueda escribir (!), lo suficientemente grande como para contener los archivos binarios y adicionales esperados, como el archivo Léame (escaso podría funcionar).

  2. Monte el DMG y asígnele un diseño manualmente en Finder o con cualquier herramienta que le convenga para hacerlo (consulte el enlace de FileStorm en la parte inferior para obtener una buena herramienta).La imagen de fondo suele ser una imagen que colocamos en una carpeta oculta ("algo") en el DMG.Coloque una copia de su aplicación allí (cualquier versión, incluso la desactualizada, servirá).Copie otros archivos (alias, Léame, etc.) que desee allí; nuevamente, las versiones desactualizadas funcionarán bien.Asegúrese de que los íconos tengan los tamaños y posiciones correctos (IOW, diseñe el DMG de la manera que desee).

  3. Desmonte el DMG nuevamente; todas las configuraciones ya deberían estar almacenadas.

  4. Escriba un script de creación de DMG que funcione de la siguiente manera:

    • Copia el DMG, por lo que el original nunca más se vuelve a tocar.
    • Monta la copia.
    • Reemplaza todos los archivos con los más actualizados (p. ej.última aplicación después de la compilación).Puedes simplemente usar mv o ídem para eso en la línea de comando.Tenga en cuenta que cuando reemplaza un archivo como ese, el ícono permanecerá igual, la posición permanecerá igual, todo menos el contenido del archivo (o directorio) permanecerá igual (al menos con lo mismo, que normalmente usamos para esa tarea) .Por supuesto, también puedes reemplazar la imagen de fondo por otra (sólo asegúrate de que tenga las mismas dimensiones).
    • Después de reemplazar los archivos, haga que el script desmonte la copia DMG nuevamente.
    • Finalmente llame a hdiutil para convertir el archivo grabable en un DMG comprimido (y no grabable).

Puede que este método no parezca óptimo, pero créame, funciona muy bien en la práctica.Puedes poner el DMG original (plantilla DMG) incluso bajo control de versiones (p. ej.SVN), por lo que si alguna vez lo cambias o lo destruyes accidentalmente, puedes volver a una revisión donde todavía estaba bien.Puede agregar la plantilla DMG a su proyecto Xcode, junto con todos los demás archivos que pertenecen al DMG (léame, archivo URL, imagen de fondo), todo bajo control de versiones y luego crear un destino (p. ej.objetivo externo llamado "Crear DMG") y allí ejecute el script DMG anterior y agregue su antiguo objetivo principal como objetivo dependiente.Puede acceder a los archivos en el árbol de Xcode usando ${SRCROOT} en el script (siempre es la raíz de origen de su producto) y puede acceder a los productos de compilación usando ${BUILT_PRODUCTS_DIR} (siempre es el directorio donde Xcode crea los resultados de la compilación) .

Resultado:En realidad, Xcode puede producir el DMG al final de la compilación.Un DMG que está listo para lanzar.No solo puede crear un DMG de liberación bastante fácil de esa manera, sino que también puede hacerlo en un proceso automatizado (en un servidor sin cabeza si lo desea), usando xcodebuild desde la línea de comandos (compilaciones nocturnas automatizadas, por ejemplo).

En cuanto al diseño inicial de la plantilla, Tormenta de archivos es una buena herramienta para hacerlo.Es comercial, pero muy potente y fácil de usar.La versión normal cuesta menos de 20 dólares, por lo que es realmente asequible.Quizás se pueda automatizar FileStorm para crear un DMG (p. ej.a través de AppleScript), nunca lo intenté, pero una vez que haya encontrado la plantilla DMG perfecta, es muy fácil actualizarla para cada versión.

Actualizar esta pregunta proporcionando esta respuesta.

appdmg es un programa de línea de comandos de código abierto, simple y fácil de usar que crea archivos dmg a partir de una especificación json simple.Eche un vistazo al archivo Léame en el sitio web oficial:

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

Ejemplo rápido:

  1. Instalar aplicacióndmg

    npm install -g appdmg
    
  2. Escribe un archivo 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. Ejecute el programa

    appdmg spec.json test.dmg
    

(descargo de responsabilidad.Soy el creador de appdmg)

Para aquellos de ustedes que estén interesados ​​en este tema, debo mencionar cómo creo el DMG:

hdiutil create XXX.dmg -volname "YYY" -fs HFS+ -srcfolder "ZZZ"

dónde

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

mi aplicación, soltardmg, es una forma sencilla de crear imágenes de disco con imágenes de fondo, diseños de íconos, íconos de volumen personalizados y acuerdos de licencia de software.Se puede controlar desde un sistema de compilación mediante la herramienta de línea de comandos "dropdmg" o AppleScript.Si lo desea, los archivos RTF de imagen y licencia se pueden almacenar en su sistema de control de versiones.

Encontré esta excelente aplicación para Mac para automatizar el proceso: http://www.araelium.com/dmgcanvas/debes echar un vistazo si estás creando un instalador dmg para tu aplicación mac

Si desea configurar un ícono de volumen personalizado, use el siguiente comando

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

Ahora crea dmg de lectura/escritura

/*to set custom icon attribute*/
SetFile -a C /Volumes/dmgName

Para crear un DMG atractivo, ahora puedes usar algunas fuentes abiertas bien escritas:

Los archivos .DS_Store almacenan la configuración de Windows en Mac.La configuración de Windows incluye el diseño de los iconos, el fondo de la ventana, el tamaño de la ventana, etc.El archivo .DS_Store es necesario para crear la ventana de imágenes montadas para preservar la disposición de los archivos y el fondo de Windows.

Una vez que haya creado el archivo .DS_Store, puede copiarlo al instalador creado (DMG).

También necesito utilizar un enfoque de línea de comandos para realizar el empaquetado y la creación de dmg "mediante programación en un script".La mejor respuesta que encontré hasta ahora es del marco de construcción de versiones del proyecto Adium (ver R1).Hay un script personalizado (AdiumApplescriptRunner) que le permite evitar la interacción con la GUI de OSX WindowsServer.El enfoque "osascript applescript.scpt" requiere que inicie sesión como constructor y ejecute la creación de dmg desde una sesión de línea de comando vt100.

El sistema de gestión de paquetes OSX no es tan avanzado en comparación con otros Unixen que pueden realizar esta tarea de forma fácil y sistemática.

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

Finalmente logré que esto funcionara en mi propio proyecto (que resulta que está en Xcode).Agregar estos 3 scripts a su fase de compilación creará automáticamente una imagen de disco para su producto que sea agradable y ordenada.Todo lo que tienes que hacer es construir tu proyecto y el DMG estará esperando en tu carpeta de productos.

Script 1 (Crear imagen de disco temporal):

#!/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 (establecer script de propiedades de ventana):

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

La medida anterior para la ventana funciona para mi proyecto específicamente debido al tamaño de mi imagen de fondo y la resolución del ícono;es posible que necesite modificar estos valores para su propio proyecto.

Script 3 (Crear script de imagen de disco final):

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

¡Asegúrese de que los archivos de imagen que está utilizando estén en el directorio $PROJECT_DIR/$PROJECT_NAME/!

Estas respuestas son demasiado complicadas y los tiempos han cambiado.Lo siguiente funciona bien en 10.9, los permisos son correctos y se ve bien.

Crear un DMG de solo lectura desde un directorio

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

Crear DMG de solo lectura con un ícono (tipo .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

Si es necesario que suceda algo más, lo más fácil es hacer una copia temporal de SRC_DIR y aplicarle cambios antes de crear un DMG.

Acabo de escribir una nueva utilidad de línea de comandos (amigable) para hacer esto.No depende de Finder/AppleScript, ni de ninguna de las API (obsoletas) de Alias ​​Manager, y es fácil de configurar y usar.

De todos modos cualquiera que esté interesado puede encuéntralo en PyPi;la documentación es disponible en Lea los documentos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top