Como faço para criar uma boa aparência DMG para Mac OS X usando as ferramentas de linha de comando?

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

Pergunta

Eu preciso criar um instalador agradável para uma aplicação Mac. Eu quero que seja uma imagem de disco (DMG), com a imagem em tamanho, layout e de fundo uma pré-definido.

Eu preciso fazer isso por meio de programação em um script, para ser integrado em um sistema de compilação existente (mais de um sistema de pacote realmente, uma vez que só criar instaladores. O constrói são feitas separadamente).

Já tenho a criação DMG feito usando "hdiutil", o que eu não descobri ainda é como fazer um layout ícone e especificar um bitmap de fundo.

Foi útil?

Solução

Depois de muita pesquisa, eu vim com esta resposta, e eu estou aqui colocá-lo aqui como uma resposta para a minha pergunta, para referência:

  1. Certifique-se de que "Permitir o acesso para dispositivos de assistência" está marcada nas Preferências do Sistema >> Acesso Universal. Ela é necessária para o AppleScript ao trabalho. Você pode ter que reiniciar depois desta mudança (que não funciona de outra forma no Mac OS X Server 10.4).

  2. Criar um R / W DMG. Deve ser maior que o resultado será. Neste exemplo, a variável bash "tamanho" contém o tamanho em Kb e o conteúdo da pasta na variável bash "fonte" será copiado para o 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 a imagem de disco, e armazenar o nome do dispositivo (que você pode querer usar o sono por alguns segundos após esta operação):

    device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
             egrep '^/dev/' | sed 1q | awk '{print $1}')
    
  4. loja a imagem de fundo (no formato PNG) em uma pasta chamada ".background" no DMG, e armazenar o seu nome na variável 'backgroundPictureName'.

  5. Use AppleScript para definir os estilos visuais (nome do .app deve estar na variável bash "applicationName", variáveis ??de uso para as outras propriedades, conforme necessário):

    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 a DMG definindo permissões corretamente, compressão e liberá-lo:

    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 
    

No Snow Leopard, o applescript acima não irá definir a posição do ícone corretamente - parece ser um bug Snow Leopard. Uma solução é simplesmente chamar de abertura / fecho depois de definir os ícones, ou seja:.

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

Outras dicas

Há um pequeno script Bash chamado criar-dmg que constrói DMGs fantasia com fundos personalizados, costume ícone de posicionamento e nome de volume.

Eu construí-lo há muitos anos para a empresa que eu corri na época; que sobrevive com a contribuição de outras pessoas desde então, e supostamente funciona bem.

Há também nó-appdmg que se parece com um esforço mais moderna e activa com base no nó. js; verificá-la também.

Não vá lá. Como um desenvolvedor de Mac de longa duração, posso assegurar-lhe, nenhuma solução é realmente funcionando bem. Eu tentei tantas soluções, mas todos eles não são muito bons. Acho que o problema é que a Apple realmente não documentar o formato de dados meta para os dados necessários.

Aqui está como eu estou fazendo isso por um longo tempo, com muito sucesso:

  1. Criar um novo DMG, gravável (!), Grande o suficiente para armazenar os arquivos binários e extra esperados como readme (trabalho poder escassa).

  2. Monte o DMG e dar-lhe um layout manualmente no Finder ou com quaisquer ferramentas lhe convier para fazer isso (veja o link FileStorm na parte inferior para uma boa ferramenta). A imagem de fundo é geralmente uma imagem que colocamos em uma pasta oculta ( ".algo") sobre a DMG. Coloque uma cópia do seu aplicativo lá (qualquer versão, mesmo um desatualizado vai fazer). Copiar outros arquivos (aliases, leia-me, etc.) que você quer lá, mais uma vez, versões desatualizadas vai fazer muito bem. Certifique-se de ícones têm os tamanhos e posições de direita (IOW, o layout da DMG do jeito que você quer que seja).

  3. Desmonte o DMG novamente, todas as configurações devem ser armazenados até agora.

  4. Dê a sua criar DMG roteiro, que funciona da seguinte forma:

    • copia o DMG, então o original nunca é tocado novamente.
    • Ele monta a cópia.
    • Ele substitui todos os arquivos com os mais modernos queridos data (app exemplo mais tardar após acumulação). Você pode simplesmente usar mv ou ditto para que na linha de comando. Note, quando você substituir um arquivo como esse, o ícone permanecerá o mesmo, a posição permanecerá a mesma, tudo, mas o arquivo (ou diretório) estadias de conteúdo o mesmo (pelo menos com ditto, que geralmente usamos para essa tarefa) . Você pode também, naturalmente, substituir a imagem de fundo com outra (apenas certifique-se que tem as mesmas dimensões).
    • Depois de substituir os arquivos, faça o roteiro desmontar o DMG copiar novamente.
    • Finalmente chamar hdiutil para converter a escrita, a um DMG comprimido (e tal não gravável).

Este método pode não óptimo som, mas confia em mim, ele funciona muito bem na prática. Você pode colocar o DMG original (modelo DMG), mesmo sob controle de versão (por exemplo SVN), então se você nunca acidentalmente mudança / destruí-lo, você pode simplesmente voltar para uma revisão, onde ele ainda estava bem. Você pode adicionar o modelo DMG ao seu projeto Xcode, juntamente com todos os outros arquivos que pertencem para a DMG (leia-me, arquivo URL, imagem de fundo), tudo sob controle de versão e, em seguida, criar um alvo (por exemplo, alvo externo denominado "Criar DMG") e não executar o script DMG de acima e adicione o seu alvo principal antigo como alvo dependente. Você pode acessar arquivos na árvore Xcode usando $ {SRCROOT} no script (é sempre a raiz fonte de seu produto) e você pode acessar produtos de construção usando $ {BUILT_PRODUCTS_DIR} (é sempre o diretório onde Xcode cria os resultados da construção) .

Resultado: Na verdade Xcode pode produzir o DMG no final da compilação. A DMG que está pronto para liberar. Não apenas você pode criar um DMG relase muito fácil dessa maneira, você pode realmente fazê-lo em um processo automatizado (em um servidor sem cabeça se você gosta), usando xcodebuild linha de comando (automatizado nightly builds, por exemplo).

Em relação ao layout inicial do modelo, FileStorm é uma ferramenta boa para fazê-lo. É comercial, mas muito poderoso e fácil de usar. A versão normal é de menos de US $ 20, por isso é muito acessível. Talvez um pode automatizar FileStorm para criar um DMG (por exemplo através de AppleScript), nunca tentou isso, mas depois de ter encontrado o DMG modelo perfeito, é realmente fácil de atualizá-lo para cada lançamento.

Trazendo esta questão até à data, fornecendo esta resposta.

appdmg é um simples, fácil de usar, programa de linha de comando de código aberto que cria DMG-arquivos de uma especificação JSON simples. Dê uma olhada no readme no site oficial:

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

exemplo rápido:

  1. Instale appdmg

    npm install -g appdmg
    
  2. Escrever um arquivo 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. Executar programa

    appdmg spec.json test.dmg
    

(disclaimer. Eu sou o criador do appdmg)

Para aqueles de vocês que estão interessados ??neste tema, devo mencionar como eu crio a DMG:

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

onde

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

Meu aplicativo, DropDMG , é uma maneira fácil de criar imagens de disco com background imagens, ícone layouts , ícones do volume de costume, e contratos de licença de software. Ele pode ser controlado a partir de um sistema de construção através da ferramenta de linha de comando "dropdmg" ou AppleScript. Se desejado, os arquivos RTF de imagem e de licença podem ser armazenados em seu sistema de controle de versão.

Eu encontrei este grande app mac para automatizar o processo - http://www.araelium.com/dmgcanvas/ você deve ter um olhar se você estiver criando instalador dmg para seu aplicativo mac

Se você quiser set ícone de volume personalizado, em seguida, use o comando abaixo

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

Agora crie leitura / gravação dmg

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

Para criar um bom olhar DMG, agora você pode apenas usar algumas fontes abertas bem escritos:

.DS_Store armazena arquivos Configurações do Windows no Mac. configurações do Windows incluem os ícones de layout, o fundo da janela, o tamanho da janela, etc. ficheiro A .DS_Store é necessário criar a janela para as imagens montadas para preservar a disposição dos ficheiros eo fundo janelas.

Depois de ter arquivo .DS_Store criado, você pode simplesmente copiá-lo para o seu instalador criado (DMG).

Eu também na necessidade de usar abordagem de linha de comando para fazer a embalagem e criação dmg "programaticamente em um script". A melhor resposta que eu encontrei até agora é de projeto Adium' Lançamento estrutura do edifício (Veja R1). Há um script personalizado (AdiumApplescriptRunner) para permitir que você evitar a interação OSX WindowsServer GUI. abordagem "applescript.scpt osascript" exigem que você faça login como construtor e executar a criação dmg de uma sessão de linha de comando vt100.

OSX sistema de gerenciamento de pacotes não é tão avançada em comparação com outros Unixen que pode fazer esta tarefa com facilidade e de forma sistemática.

R1: http://hg.adium.im/adium-1.4/ arquivo / 00d944a3ef16 / Lançamento

Eu finalmente consegui esse trabalho no meu próprio projeto (que passa a ser no Xcode). Adicionando estes 3 scripts para sua fase de construção irá criar automaticamente uma imagem de disco para o seu produto que é bonito e arrumado. Tudo que você tem a fazer é construir o seu projeto eo DMG estará esperando na sua pasta de produtos.

Script 1 (Criar Temp imagem de disco):

#!/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 Properties Window 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=$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

A medição acima para o trabalho janela para o meu projeto especificamente devido ao tamanho do meu pic fundo e resolução de ícone; pode ser necessário modificar esses valores para o seu próprio projeto.

Script 3 (Adicione final imagem de disco Script):

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

Certifique-se os ficheiros de imagem que você está usando são no $ project_dir / $ PROJECT_NAME / diretório!

Estas respostas são muito complicado e os tempos mudaram. As seguintes obras sobre 10.9 muito bem, permissões estão correctas e parece bom.

Criar uma única leitura DMG de um diretório

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

Criar DMG somente leitura com uma (tipo .icns) ícone

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

Se as necessidades de qualquer outra coisa para acontecer, estes coisa mais fácil é fazer uma cópia temporária do SRC_DIR e aplicar as alterações para que antes de criar um DMG.

Acabo de escrever um novo utilitário (amigável) de linha de comando para fazer isso. Ele não depende de localizador / AppleScript, ou em qualquer um dos (reprovado) Alias ??Gerente de APIs, e é fácil de configurar e usar.

De qualquer forma, qualquer um que é lata interessados ?? encontrá-lo no PyPI ; a documentação é acessível em Leia a documentação .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top