associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Você não tem permissão para executar esta ação.

Excluir mensagem

InstaladorWindows

1. Criando um instalador para Windows

1.1. Motivos

Um belo dia precisei criar um instalador de uma aplicação PyGTK para Ruindow$$ aqui no serviço.

Procurei vários tutoriais, e a maioria deles apontava para o uso do py2exe. Mas minha aplicação não era uma aplicação comum, ela utilizava matplotlib para gerar gráficos. O grande problema disso é:

  • py2exe me parece mais uma gambiarra para esconder o código do programa que não funciona direito.
    • Não faça isso! Seja livre! Não caia na besteira de tentar ganhar dinheiro por domínio de conhecimento. Ganhe com seu serviço! Com seu esforço! Python existe graças a esses princípios! Vamos passar a diante esse bom exemplo!
  • py2exe é muito complicado
    • No meu caso, para utilizar GTK junto com py2exe ja existe uma configuração "especial" para funcionar descrito no site oficial, e para utilizar matplotlib existia outra configuração diferente, mas as 2 não casavam. Perdi muitas horas tentando fazer funcionar meu instalador com py2exe.

E a solução foi:

  • Retirei o py2exe da jogada
  • Instalei tudo que precisava numa máquina virtual e fiz funcionar normalmente
  • Copiei toda a instalação do python dessa máquina virtual e a instalação do gtk para a pasta do instalador, do jeito que ficou após a instalação
  • Utilizei os truques do portable python para transformar minha instalação do Python portável

  • Customizei meu script de inicialização do programa para adicionar o GTK
  • Criei o instalador NSIS

Adiante vou mostrar em detalhes cada um desses passos!

1.2. Instalação

Primeiro de tudo, instale o Python e os módulos necessários para rodar seu programa no windows. No meu caso, instalei os seguintes pacotes:

  • python-2.6.4.msi
  • pygobject-2.14.2-2.win32-py2.6.exe
  • pycairo-1.4.12-2.win32-py2.6.exe
  • pygtk-2.12.1-3.win32-py2.6.exe
  • gtk2-runtime-2.16.6-2009-12-01-ash.exe
  • numpy-1.4.0rc1-win32-superpack-python2.6.exe
  • matplotlib-0.99.1.win32-py2.6.exe
  • pyserial-2.5-rc1.win32.exe
  • PyMEC1000-0.1.zip (minha aplicação)

Tenha certeza de conseguir executar seu programa após a instalação/configuração:

pymec1000_win

Aplicação rodando

1.3. Transformando o Python Portável

O portable python utiliza um truque não muito difícil de reproduzir. Se voce copiar sua instalação do Python para outra máquina, ela vai executar tranquilamente se o computador possuir as DLLs necessárias para rodar o Python. O que acontece nessa distribuição é exatamente isso, é colocado na pasta do Python as DLLs necessárias para a execução do mesmo. Só precisamos baixar o seguinte arquivo e descompactar na pasta do Python.

1.4. Criando o instalador

Para criar o instalador, copiamos a pasta do Python e do GTK para outra pasta. No meu exemplo, copiei para c:\instalador, conforme a figura abaixo.

ambiente_instalador

Ambiente do instalador

Note que o meu programa foi instalado dentro do python, e deixei na raiz da pasta do instalador o arquivo que importa meu módulo e executa o programa. Antes disso esse programa também seta onde está meu GTK para o programa funcionar1:

   1 #!/usr/bin/env python
   2 import os
   3 
   4 os.putenv('PATH',
   5           os.path.abspath(os.path.join('GTK2-Runtime',
   6                                        'lib')))
   7 
   8 from pymec1000.interface import main
   9 
  10 main()

Logo após, utilizamos os programa NSIS e HM NSIS Edit para criar o script do instalador.

No meu caso, o script ficou da seguinte forma:

; Script generated by the HM NIS Edit Script Wizard.



; HM NIS Edit Wizard helper defines

!define PRODUCT_NAME "PyMEC1000"

!define PRODUCT_VERSION "0.1"

!define PRODUCT_PUBLISHER "Maxwell Bohr"

!define PRODUCT_WEB_SITE "http://www.maxwellbohr.com.br"

!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\pythonw.exe"

!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"

!define PRODUCT_UNINST_ROOT_KEY "HKLM"



; MUI 1.67 compatible ------

!include "MUI.nsh"



; MUI Settings

!define MUI_ABORTWARNING

!define MUI_ICON "mb.ico"

!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"



; Welcome page

!insertmacro MUI_PAGE_WELCOME

; License page

;!insertmacro MUI_PAGE_LICENSE "c:\path\to\licence\YourSoftwareLicence.txt"

; Directory page

!insertmacro MUI_PAGE_DIRECTORY

; Instfiles page

!insertmacro MUI_PAGE_INSTFILES

; Finish page

!insertmacro MUI_PAGE_FINISH



; Uninstaller pages

!insertmacro MUI_UNPAGE_INSTFILES



; Language files

!insertmacro MUI_LANGUAGE "PortugueseBR"



; MUI end ------



Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"

OutFile "PyMEC1000-0.1_Setup.exe"

InstallDir "$PROGRAMFILES\PyMEC1000"

InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""

ShowInstDetails show

ShowUnInstDetails show



Section "MainSection" SEC01

  SetOutPath "$INSTDIR"

  SetOverwrite ifnewer

  File "Python26\pythonw.exe"

  CreateDirectory "$SMPROGRAMS\PyMEC1000"

  CreateShortCut "$SMPROGRAMS\PyMEC1000\PyMEC1000.lnk" "$INSTDIR\Python26\pythonw.exe" "pymec1000-interface.pyw" "$INSTDIR\mb.ico"

  CreateShortCut "$DESKTOP\PyMEC1000.lnk" "$INSTDIR\Python26\pythonw.exe" "pymec1000-interface.pyw" "$INSTDIR\mb.ico"

  SetOverwrite try
  File /r *

SectionEnd



Section -AdditionalIcons

  WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"

  CreateShortCut "$SMPROGRAMS\PyMEC1000\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"

  CreateShortCut "$SMPROGRAMS\PyMEC1000\Uninstall.lnk" "$INSTDIR\uninst.exe"

SectionEnd



Section -Post

  WriteUninstaller "$INSTDIR\uninst.exe"

  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\Python26\pythonw.exe"

  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"

  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"

  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\mb.ico"

  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"

  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"

  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"

SectionEnd




Function un.onUninstSuccess

  HideWindow

  MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."

FunctionEnd



Function un.onInit

  MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2

  Abort

FunctionEnd



Section Uninstall

  Delete "$DESKTOP\PyMEC1000.lnk"



  RMDir /r "$SMPROGRAMS\PyMEC1000"

  RMDir /r "$INSTDIR"



  DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"

  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"

  SetAutoClose true

SectionEnd

Após compilar o script, o resultado é um instalador tão profissional quanto os instaladores encontrados na maioria dos programas.

instalador_nsis

Instalador

Espero que tenham gostado das dicas desse tutorial! e aguardo sugestões para melhorias no canal #python-br !

Abraços! ^__^

Rodrigo

python -c "print .join([chr(154 - ord(c)) for c in 'H+6(13+zT5((51(9z65zG+% 9zmz(+645(\'+%Z3-91.l7+-'])"


  1. "Note que no meu caso, instalei o GTK com a opção de colocar as dlls na pasta lib, por isso meu script ficou desse jeito" (1)