Criando um instalador para distribuir suas aplicações Windows

No meu artigo passado, onde expliquei como criar um executável para uma aplicação Java, falei das dificuldades de criação de um instalador que um dos nossos alunos comentou. Então dando continuidade a este tema, neste artigo expliquei como criar o instalador em si.

Neste ponto é importante que já tenha gerado o executável da aplicação. Você pode ver como realizar este procedimento no meu artigo passado.

Java - Arquivos e I/O API
Curso de Java - Arquivos e I/O API
CONHEÇA O CURSO

Inno Setup

Existem várias aplicações que possibilitam a criação de um instalador para o Windows. Para este artigo irei utilizar o Inno Setup, por se tratar de uma aplicação clássica, que possui muito material informativo e é gratuita.

Você pode efetuar o download desta ferramenta no site: http://www.jrsoftware.org/isinfo.php

Só que antes de vê-la é necessário verificarmos se possuímos todas as dependências da aplicação. Como neste artigo irei utilizar a aplicação abordada no artigo passado, sei que ela utiliza o MySQL como banco de dados, então será necessário configurá-lo durante a instalação da aplicação. E a aplicação também necessita do JRE, então ele precisa ser empacotado junto do executável.

Aqui cabe um parênteses, o MySQL não é o banco de dados ideal para uma aplicação destkop simples, como a deste artigo. Por causa deste banco, a aplicação irá ocupar muito espaço em disco, irá demorar para ser instalada e terá a dependência de um serviço que precisa ficar ativo.

Um banco de dados mais apropriado para esta situação seria o SQLite, que é mais leve e mais fácil de ser configurado.

De qualquer forma, vamos ver como configurar o MySQL durante a instalação da aplicação.

Configurando a instalação do banco de dados

Para configurar o banco de dados utilizarei um arquivo batch e a versão noinstall do MySQL Community Server. Esta versão é o arquivo zip disponibilizado no site do banco. Com isso, não haverá necessidade de iniciar um instalador.

Após efetuar o download da versão compactada do banco, é necessário extrai-lo. Entre os arquivos extraídos pode-se remover os arquivos com extensão *.pdb. Os arquivos com esta extensão são utilizados para depuração e a nossa aplicação não necessitará deste recurso.

Ao realizar este procedimento se reduz o tamanho da pasta do banco.

Agora é necessário configurá-lo via um arquivo batch. Com isso, poderemos indicar para o Inno Setup que este arquivo deve ser executado durante a instalação da aplicação e removido ao final dela. Desta forma, o banco será configurado e instalado em paralelo com a aplicação e o usuário não notará.

O nosso foco aqui não é como funciona o processo de configuração do MySQL via linha de comando, que é o recurso que utilizaremos para configurá-lo por um arquivo batch. Você pode ver como realizar esta configuração na documentação do banco.

Seguindo a documentação, o arquivo batch da aplicação ficará com o conteúdo abaixo:

@echo off

echo Criando a pasta data, utilizadas pelo MySQL

set mypath=%cd%

set mysqlpath=%mypath%\..\mysql

if not exist "%mysqlpath%\data" mkdir "%mysqlpath%\data"

echo Inicializando o MySQL. Criando o conteúdo da pasta data

"%mysqlpath%/bin/mysqld.exe" --initialize-insecure --user=mysql --basedir="%mysqlpath%" --datadir="%mysqlpath%\data"

echo Definindo o MySQL como um serviço

"%mysqlpath%\bin\mysqld.exe" --install MySQL

echo Iniciando o serviço criado

sc start MySQL

echo Verificando se o serviço esta ativo

:INITDATA
sc query "MySQL" | find "RUNNING"
if "%ERRORLEVEL%"=="0" (
    echo Serviço ativo ...

    echo Configurando a base de dados...

    echo Definindo uma senha para o usuário root...

    "%mysqlpath%\bin\mysql.exe" -uroot --skip-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'iTagAfrH5ej';"

    echo Criando o usuário utilizado pela aplicação e atribuindo as permissões dele

    "%mysqlpath%\bin\mysql.exe" -uroot -piTagAfrH5ej -e "CREATE USER 'appjavafx'@'localhost' IDENTIFIED BY 'app1java2fx3';GRANT CREATE, SELECT, INSERT, UPDATE, DELETE ON *.* TO 'appjavafx'@'localhost';FLUSH PRIVILEGES;"

    echo Criando o banco de dados da aplicação

    "%mysqlpath%\bin\mysql.exe" -uappjavafx -papp1java2fx3 -e "CREATE DATABASE appjavafx;"

    echo Criando a tabela utilizada pela a aplicação

    "%mysqlpath%\bin\mysql.exe" -uappjavafx -papp1java2fx3 -e "CREATE TABLE appjavafx.contatos (id INT NOT NULL AUTO_INCREMENT, nome VARCHAR(256) NOT NULL, idade MEDIUMINT NOT NULL, telefone CHAR(15) NOT NULL, PRIMARY KEY (id));"

) else (
    echo Serviço ainda não iniciado, aguardando 5 segundos
    ping 127.0.0.1 -n 6 > nul
    goto INITDATA
)

Note que é exibida uma mensagem indicando o que cada comando faz. Mas é bom frisar as linhas iniciais:

set mypath=%cd%

set mysqlpath=%mypath%\..\mysql

Nelas são obtidas a pasta atual (a pasta onde a aplicação foi instalada) e a pasta do MySQL. Isso será necessário para executar os demais comandos do arquivo.

Com este arquivo definido e o banco de dados baixado, podemos configurar o instalador no Inno Setup.

Criando o instalador no Inno Setup

Após configurar o instalador da Inno Setup, ao iniciá-lo será apresentada a tela abaixo:

Como é possível notar, o Inno Setup gera o instalador com base nas configurações definidas em um script. Esta ferramenta possui uma grande gama de opções, que não irei abordar em detalhes aqui. O foco serão os recursos utilizados para criar o instalador da aplicação deste artigo.

Nesta primeira tela, optei pela opção “Create a new script file using the Script Wizard“. Com isso será exibido um assistente que irá facilitar a criação do script:

Neste assistente a tela mais importante é onde é indicado o executável e as suas dependências:

Pois caso alguma dependência não seja selecionada, a aplicação pode não funcionar corretamente. Ao final do assistente será criado um script parecido com o abaixo:

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "AppJavaFX"
#define MyAppVersion "1.0"
#define MyAppPublisher "Treinaweb Cursos"
#define MyAppURL "https://www.example.com.br/"
#define MyAppExeName "AppJavaFx.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{0CFD790F-D36E-4569-A5CD-D97CB6B6732D}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DisableProgramGroupPage=yes
PrivilegesRequired=admin
OutputBaseFilename=AppSetup
Compression=lzma
SolidCompression=yes
WizardStyle=modern

[Languages]
Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]
Source: "C:\Curso\Java\AppJavaFx.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Curso\Java\installmysql.bat"; DestDir: "{app}/bin"; Flags: ignoreversion deleteafterinstall
Source: "C:\Users\trein\Downloads\mysql-8.0.18-winx64\*"; DestDir: "{app}/mysql"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "C:\Curso\Java\java-runtime\*"; DestDir: "{app}/java-runtime"; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\bin\installmysql.bat"; Parameters: "install"; Flags: runascurrentuser runhidden
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

[UninstallDelete]
Type: filesandordirs; Name: "{app}/mysql/data"

Algumas configurações que o assistente não define adicionei diretamente no script, como a indicação que o arquivo batch deve ser executado em durante a instalação:

[Run]
Filename: "{app}\bin\installmysql.bat"; Parameters: "install"; Flags: runascurrentuser runhidden

Também indiquei que este arquivo deve ser excluído ao final do processo:

Source: "C:\Curso\Java\installmysql.bat"; DestDir: "{app}/bin"; Flags: ignoreversion deleteafterinstall

Como ele contém informações sensíveis (as senhas dos usuários do banco), não pode ficar na pasta da aplicação.

Para gerar o executável, selecione a opção Build > Compiler (Ctrl+F9) ou Run (F6). Caso opte pela opção Run, o instalador será iniciado após a sua criação.

Windows - Fundamentos para desenvolvedores
Curso de Windows - Fundamentos para desenvolvedores
CONHEÇA O CURSO

Iniciando o instalador

Com o instalador gerado é importante executá-lo para verificar se foi criado corretamente. Ele pode ser executado no computador atual, onde exibirá o assistente:

Podemos seguí-lo, que ao final é perguntando se a aplicação deve ser iniciada:

Caso a aplicação seja iniciada sem nenhum erro é porque o instalador foi criado corretamente.

Também é possível verificar na pasta da aplicação quais foram os arquivos criados:

Com tudo certo, a aplicação pode ser distribuída para outros usuários.

Fico por aqui, até o próximo artigo.

Deixe seu comentário

Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo.