Você está na página 1de 22

Criando instaladores para Windows com

o Inno Setup
Introdução

O Inno Setup é um gerador de programas de instalação para Windows, gratuito e de


código aberto. É um dos instaladores mais bem feitos e usados, concorre diretamente
com muitos softwares comerciais do tipo.

Voltado a desenvolvedores diversos, ele facilita a criação de um programa de instalação


para suas aplicações, com um visual moderno e clássico de instalador, se mantendo
prático e cheio de recursos. Ter um instalador próprio mal feito ou feito na correria pode
ser ruim para seus programas, é bom preparar uma instalação bem feita - afinal, o
primeiro contato dos usuários com seu programa geralmente se dá durante a instalação
:)

Entre várias outras coisas, o Inno Setup permite criar chaves no registro e em arquivos
INI, além do básico de um instalador: copiar arquivos para alguma pasta e a criação de
atalhos. Ele tem várias propriedades que podem ser configuradas, como limitar a
instalação a somente administradores, registrar DLL/OCX, instalar fontes, e muito mais.
Ainda cria um desinstalador, que pode remover completamente seu programa. Uma
grande possibilidade é que ele tem suporte a uma espécie de "programação" interna,
onde você pode personalizar o instalador usando algumas funções como se estivesse
num ambiente de programação. É possível também chamar funções de DLLs, ou seja:
as possibilidades são imensas.

Ele pode ser baixado em:

http://www.jrsoftware.org/

A geração dos instaladores com o Inno Setup se dá por meio de um script. O compilador
dele lê o script e gera um executável, unindo seus arquivos, as configurações e o
módulo do instalador (um executável pronto, que realizará a instalação baseando-se nas
configurações definidas). O resultado é um único arquivo .exe, que pode ser facilmente
distribuído. O instalador dos seus programas terá esta aparência:
A criação do script, que é basicamente um arquivo de texto puro (com a extensão .iss),
pode ser feita digitando-se os comandos manualmente ou então usando o assistente de
criação do Inno - que gera um projeto básico. A forma mais fácil de criar um novo
instalador é usar o assistente, e depois modificar o arquivo do projeto manualmente. E
claro, modificar várias vezes, compilar e testar, até ficar pronto :)

O assistente dele faz o básico, vou me concentrar em mostrar alguns pontos importantes
para um bom instalador, como a criação de chaves no registro, e orientação sobre como
"programar" no Inno Setup, dando exemplo de uso de uma DLL externa.

O assistente do Inno exibe algumas telas, basta você ir preenchendo com as informações
do seu programa e avançando:
Ao final, ele tem um script básico, que você poderá modificar sem grandes dificuldades.
Antes de começar, é bom ter organizado e separado os arquivos do seu programa. Deixe
tudo o que deverá existir no sistema do usuário em uma pasta, com subpastas, se
necessário - toda a estrutura será copiada. Separe também o texto da licença da
aplicação, de preferência num arquivo TXT.

Iniciando o compilador do Inno Setup, escolha a opção "Create a new script using the
Script Wizard". Vá preenchendo as informações conforme solicitadas, e ao concluir,
terá o script padrão gerado. Considerando que ele é um gerador de programas de
instalação para um software que você tenha criado, não haverá dificuldade em passar
pelo assistente. Para compilar seu projeto, tecle CTRL+F9, e para compilar e testar, F9
apenas (como no Delphi). Você pode usar os menus ou botões da barra de ferramentas
também, claro. O ambiente do Inno funciona como um debugger, mostrando quando
algo estiver errado (inclusive indicando a linha), além de exibir um log da instalação em
andamento (enquanto você testar o instalador a partir da interface dele). O arquivo para
ser distribuído será o setup.exe, que por padrão fica na pasta "Output", onde estiver
salvo o script.

A estrutura básica do script do Inno Setup é esta:

[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={{4BD6DFD3-105A-4921-B253-3F15E6022B5C}
AppName=My Program
AppVerName=My Program 1.5
AppPublisher=My Company, Inc.
AppPublisherURL=http://www.example.com/
AppSupportURL=http://www.example.com/
AppUpdatesURL=http://www.example.com/
DefaultDirName={pf}My Program
DefaultGroupName=My Program
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

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

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

[Files]
Source: "C:Program Files (x86)Inno Setup 5ExamplesMyProg.exe"; DestDir: "{app}";
Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{group}My Program"; Filename: "{app}MyProg.exe"
Name: "{commondesktop}My Program"; Filename: "{app}MyProg.exe"; Tasks:
desktopicon
[Run]
Filename: "{app}MyProg.exe"; Description: "{cm:LaunchProgram,My Program}";
Flags: nowait postinstall skipifsilent

Veja que o arquivo tem o estilo dos arquivos INI, sendo bem fácil de editar. Algumas
seções permitem vários parâmetros, neste caso eles devem ser separados por ponto-e-
vírgula, além de terem seu conteúdo declarado entre aspas, se tiver espaços.

A seção [Setup] define informações básicas do programa de instalação, como o nome da


aplicação, URL do produtor, pasta padrão para instalação, etc. O Inno Setup usa
algumas constantes de pastas próprias; você pode ver uma relação completa na ajuda
dele. Por exemplo, {pf} retorna o caminho completo da pasta "Arquivos de programas"
no sistema do usuário - independente do idioma do Windows ou partição em que ela
esteja. Na seção [Setup], várias coisas podem ser ativadas ou desativadas, como a
compressão, a exibição de uma licença de uso, a possibilidade de proteger a instalação
com uma senha, entre muitas outras. As entradas nesta seção são simples, sendo
basicamente no estilo Diretiva=Opção.

A seção [Languages], como o nome sugere, permite definir os idiomas da instalação. No


assistente você pode escolher vários idiomas, ou modificar as entradas aqui,
adicionando novas linhas para os idiomas desejados. Por exemplo, para manter o
instalador em inglês e português, você colocaria:

[Languages]

Name: "brazilianportuguese"; MessagesFile:


"compiler:LanguagesBrazilianPortuguese.isl"

Name: "english"; MessagesFile: "compiler:Default.isl"

O "Default.isl" é o arquvio de texto com as mensagens para inglês, ele está na pasta do
Inno Setup (por isso pode-se usar "compiler:", que retorna a pasta do compilador do
Inno). O Inno Setup gera instaladores multi-linguagem, e caso tenha mais de um idioma
definido, aparecerá uma caixa de diálogo para seleção da linguagem no começo da
instalação.

Das outras seções, a [Files] é a mais importante. Ela define as pastas e arquivos que
serão instalados no sistema. A [Icons] permite a criação de atalhos, a [Run] a execução
de comandos logo após a conclusão da instalação, e a [Tasks] permite criar "tarefas",
itens de checkbox que aparecerão antes de iniciar a instalação, podendo ser marcados ou
desmarcados pelo usuário. As entradas nas outras seções referenciando uma tarefa
previamente definida na seção [Tasks] só serão executadas se o usuário deixar marcada
a opção correspondente, durante a instalação.

O uso do Inno não é difícil, mas você precisa dedicar um tempinho até entender como
as entradas do script dele se relacionam. Na pasta "Examples", dentro da pasta do Inno,
existem exemplos básicos sem muitas entradas - permitindo que você estude um assunto
por vez. Nesse artigo vou destacar alguns meios de usar o Inno para gerar instaladores
mais profissionais e responsáveis, sem ficar usando muito as opções "padrões" apenas.
Particularmente fiz algumas modificações no Inno Setup, e lancei um fork dele com o
nome Mep Installer. Traduzi o programa inteiro e o conteúdo da ajuda (pelo menos dos
recursos que mantive). O material serve como um ótimo tutorial e referência em
português de boa parte dos recursos do Inno Setup, e pode ser lido sem precisar instalar
o programa, em:

http://www.mephost.com/software/help/mpist14/ajuda.htm

Basta desconsiderar o que não se aplicar ao Inno :)

Visão geral de um instalador, e noções básicas

O instalador é o programa que vai instalar os arquivos e configurações do seu programa


no sistema do usuário. É importante que ele seja bem feito, e responsável - que limpe
tudo o que fizer, numa desinstalação. Algumas observações que você deve ter em
mente:

• É recomendável que o programa seja instalado apenas por um administrador.


Usuários limitados não podem gravar coisas em chaves globais do registro, nem
em pastas do sistema (como a Arquivos de programas). Apesar de ser possível o
usuário gravar coisas nas suas pastas pessoais (podendo até instalar o programa
nela, se as características da instalação permitir), com a vinda do Windows Vista
e o XP, popular com o NTFS por padrão, é bom restringir a instalação aos
administradores. No Windows XP com o HD formatado em FAT32, um usuário
limitado até pode instalar coisas na Arquivos de programas, mesmo que não
possa gravar dados em algumas chaves do registro. Já com o sistema de arquivos
NTFS, padrão no Vista também, não tem como ele gravar dados na Arquivos de
programas. Nas versões recentes do Inno Setup, por padrão, a instalação só pode
ser feita por um administrador. Se quiser permitir que usuários limitados
executem seu instalador, então adicione na seção [Setup] esta linha:
PrivilegesRequired=none.

• Na desinstalação, limpe tudo o que o seu programa colocar, mas tome o cuidado
de não apagar arquivos do usuário. O Inno Setup remove uma boa parte do que
ele faz na instalação automaticamente. Mas em algumas situações, alguns
arquivos podem permanecer no HD. Tome o cuidado de remover estes arquivos
(comentarei como logo mais).

• Em coisas exclusivas do seu programa (pastas, chaves do registro e atalhos), use


um nome que provavelmente só o seu programa use, para evitar conflitos com
outros programas que possam existir no sistema do usuário.

Entendendo melhor o arquivo de projeto do Inno Setup


O arquivo de projeto é formado por seções, grupos de opções e configurações. Os
nomes das seções são identificados entre colchetes, e aparecem em negrito na tela do
compilador. Os itens referentes a uma determinada seção devem estar "dentro" dela.
Algumas seções possuem itens como diretivas, idênticas aos arquivos INI. Por exemplo:

[Setup]

AppName=Meu Programa

AppPublisher=Meu nome

Outras seções podem possuir mais parâmetros, geralmente separados por um ponto-e-
vírgula. Veja:

[Files]

Source: "MeuPrograma.exe"; DestDir: "{app}"

Não é recomendável especificar duas vezes uma mesma seção, coloque as diretivas ou
parâmetros de uma mesma seção embaixo da mesma identificação dela.

Você pode colocar comentários dentro do script. Comentários são textos que não são
compilados, eles apenas indicam alguma coisa, em especial para quem irá ler ou
trabalhar com o script ("script" é o "texto" do arquivo de projeto). Basta iniciar uma
linha com o ponto-e-vírgula:

; Isto é um comentário... Blá, Blá, Blá......

Se você possui um arquivo de projeto com informações que deverão se repetir em várias
instalações, pode utilizar a diretiva #include. O conteúdo do arquivo indicado será
inserido no local especificado, e após ele as informações que estiverem serão
continuadas, como se fossem um arquivo só. A sintaxe é:

#include "meuarquivo.iss"

A extensão não precisa ser necessariamente .iss, pode ser outra se você quiser, como
.txt, por exemplo.

O arquivo informado deverá estar na mesma pasta do arquivo de projeto, ou então você
pode informar o caminho completo (por exemplo, "C:Minha pastaMeu arquivo.iss"). Se
o arquivo estiver na mesma pasta do compilador, você pode utilizar assim: #include
compiler:teste.iss. Aliás, "compiler:" será substituído pelo caminho da pasta do
compilador, em diversas seções.

Parâmetros nas seções


Todas as seções do arquivo de projeto, com exceção de [Setup], [Messages],
[CustomMessages], e [LangOptions], contém linhas separadas em parâmetros. Veja o
seguinte exemplo, da seção [Files]:

[Files]

Source: "MEUPROGRAMA.EXE"; DestDir: "{app}"

Source: "AJUDA.HLP"; DestDir: "{app}"

Source: "LEIAME.TXT"; DestDir: "{app}"; Flags: isreadme

Cada parâmetro consiste em um nome, seguido por um identificador, e então um valor.


Exceto em alguns poucos casos, os parâmetros são opcionais. Eles assumirão um valor
padrão se não forem especificados. Múltiplos parâmetros em uma linha podem ser
separados por ponto-e-vírgula, e podem estar em qualquer ordem.

Geralmente se utilizam aspas duplas (") para definir o valor de um parâmetro definido
pelo usuário, como por exemplo o nome de um arquivo. Usar aspas quase sempre não é
obrigatório, mas é necessário quando o valor tiver espaços.

Se precisar utilizar aspas duplas em alguma definição, coloque duas aspas duplas
consecutivas, para evitar conflito com as aspas delimitadoras do parâmetro. A linha a
seguir:

"Este exemplo ""contém aspas"" embutidas"

Ficaria assim, após a compilação:

Este exemplo "contém aspas" embutidas

Se você quiser que o valor de um parâmetro seja uma única aspa dupla, utilize então
quatro caracteres de aspas duplas: """". Os caracteres das extremidades cercam o valor
como sendo um valor definido pelo usuário, e os dois do meio são para gerar um único
caractere de aspa.

Instalação de arquivos: dicas úteis

O assistente de criação de script do Inno cria uma entrada para cada arquivo que você
adicionar, na seção [Files]. Por exemplo:

[Files]

Source: "C:programaPrograma.exe"; DestDir: "{app}"; Flags: ignoreversion

Source: "C:programaLeiame.txt"; DestDir: "{app}"; Flags: ignoreversion


Source: "C:programaFunções.dll"; DestDir: "{app}"; Flags: ignoreversion

Conforme você for tendo muitos arquivos, ou pastas e subpastas, essa idéia pode ficar
confusa. A minha recomendação é criar uma pasta e deixar nela todos os arquivos do
seu programa, incluindo subpastas, exatamente como você quer que eles fiquem na
pasta do seu programa no sistema dos usuários. Assim, a seção [Files] teria uma entrada
só:

[Files]

Source: "C:programa*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs

Tudo o que estiver na pasta "C:programa" será copiado para a pasta da aplicação (seja
ela qual for, dado o uso da constante {app}, que retornará o caminho do seu programa
no sistema dos usuários). Para incluir as subpastas e tudo o que existir dentro delas
também, é necessário adicionar a flag recursesubdirs (note ela no final da linha acima).

Se você precisar copiar arquivos para outros lugares, como a pasta do Windows, por
exemplo, pode deixá-los numa pasta separada (fora da "C:programa", no exemplo) e
incluir uma nova entrada na seção [Files], para o novo arquivo:

Source: "C:teste.dll"; DestDir: "{win}"; Flags: ignoreversion

As constantes de pastas retornam o caminho correto da pasta no sistema do usuário,


independente do idioma do Windows ou da partição em que ele estiver instalado. Você
pode usá-las na seção [Files] e em uma série de outras, como na [Icons] ou na [Run]. A
pasta padrão do seu programa fica dentro da Arquivos de programas, um local útil para
guardar os programas. Se você quiser escolher outro local, troque o valor da diretiva
DefaultDirName na seção [Setup]:

DefaultDirName={pf}Meu programa

Para a maioria das instalações, não é necessário alterar esse caminho. O instalador
gravará no registro (na mesma chave de desinstalação) o caminho em que for instalado,
e caso uma nova versão do programa for instalada, ele manterá a pasta existente como
padrão.

Ele detecta se o programa já está instalado ou não com base no valor da diretiva AppId,
ID da aplicação, na seção [Setup]. Quando você fizer uma nova versão do seu
programa, que não puder ser entendida como uma atualização da atual (ou que possa
coexistir com ela no sistema), altere o valor da AppId. Mas não faça isso se você
pretende que o programa seja atualizável, por exemplo, da versão 1.2 para 1.5. É bom
escolher um nome para a AppId que só o seu programa use, e seus programas diferentes
também deverão usar IDs diferentes.

Uma outra recomendação minha é manter o arquivo de projeto numa pasta, e dentro
dessa pasta a pasta com os arquivos do programa a serem inclusos. Exemplo de
estrutura:

instalador.iss
leiame.txt

licença.txt
pasta_de_arquivos_do_programa

Assim, dentro do arquivo .iss você pode referenciar os arquivos usando caminhos
relativos, como por exemplo:

[Files]

Source: "pasta_de_arquivos_do_programa*"; DestDir: "{app}"; Flags: ignoreversion


recursesubdirs

Se precisar mover a pasta de lugar, leve tudo junto com ela. Dessa forma você não
precisará editar o arquivo para retirar a referência estática, como C:pasta, por exemplo.

Criação de atalhos no menu Iniciar

A criação de atalhos pode ser configurada na seção [Icons]. Tem esta sintaxe:

[Icons]

Name: "{group}Meu Programa"; Filename: "{app}MeuPrograma.exe"

O parâmetro "Name" recebe o caminho do atalho, sem precisar colocar a extensão .lnk.
Por padrão, o Inno Setup cria uma subpasta do menu "Iniciar > Programas". É útil
quando você instala vários atalhos, no mesmo grupo de programa (ou se quiser separar
um grupo de atalhos para a sua empresa, e dentro dela colocar os atalhos dos
programas). Esse caminho pode ser alterado por padrão na diretiva DefaultGroupName,
da seção [Setup].

Agora, se seu programa só vai instalar um atalho (por exemplo, um navegador, ou um


editor de textos), é recomendável que ele fique direto no "Iniciar > Programas",
economizando o caminho para o usuário. Para isso, basta alterar a entrada na seção
[Icons], deixando-a assim:

[Icons]

Name: "{commonprograms}Meu Programa"; Filename: "{app}MeuPrograma.exe"

A constante {commonprograms} retorna o caminho da pasta que guarda os atalhos do


menu Iniciar, comum para todos os usuários. A {userprograms} retorna o caminho da
mesma pasta, mas sob o perfil do usuário. É recomendável usar a primeira. Se o usuário
que instalar o programa não possuir direitos administrativos, então a pasta
correspondente do perfil dele será usada automaticamente, em vez da pasta global.

Os atalhos serão excluídos na desinstalação apenas se o instalador os criar (ou se uma


versão anterior do seu programa os tiver criado, mantendo a mesma AppId). Mas nada
impede que você exclua arquivos ou atalhos na desinstalação, como vou comentar mais
à frente.

Criando chaves no registro

A criação de chaves no registro durante a instalação pode ser feita com a função
[Registry]. Algumas flags especiais devem ser usadas nas chaves que o seu programa
criar, para que elas possam ser removidas automaticamente na desinstalação. Já nas
chaves públicas ou do Windows, em que o seu programa simplesmente alterar alguns
valores, tenha cuidado: nunca use a flag para remoção na desinstalação.

As entradas da seção [Registry] têm basicamente esta sintaxe:

[Registry]

Root: HKCU; SubKey: ChaveSubchave; ValueType: TipoDoValor; ValueName:


NomeDoValor; ValueData: DadoDoValor;

O parâmetro Root define a chave root do registro que será alterada. Você deve colocar
HKCU para a HKEY_CURRENT_USER, ou HKLM, para a
HKEY_LOCAL_MACHINE (entre outras). No SubKey, defina o caminho desejado.
Ele não precisa existir no sistema. Se não existir, será criado automaticamente. Por
exemplo, "SoftwareMinha EmpresaMeu Programa". Lembre-se de colocar textos que
contenham espaços entre aspas. Em ValueType, defina o tipo do valor, que pode ser
dword (inteiro), string (os mais usados), entre alguns outros. Para valores booleanos,
use dword, e atribua ao valor 1 para True, ou 0 para False. Em ValueData, como era de
se esperar, coloque o dado do valor. Se for uma string, prefira colocar entre aspas. Um
exemplo:

Root: HKCU; SubKey: "SoftwareMinha EmpresaMeu programa"; ValueType: dword;


ValueName: UsarCoresPersonalizadas; ValueData: 1;

Isso colocaria o valor 1 neste local:

HKEY_CURRENT_USER Software Minha Empresa Meu programa, valor dword


"UsarCoresPersonalizadas", com o valor 1. Outro exemplo, agora com uma string, que
uso num dos meus programas:

Root: HKCU; SubKey: "SoftwareMepMep Texto"; ValueType: string; ValueName:


Skin; ValueData: "{app}skins_Default Mep Texto 5.skn";

Repare que você pode usar constantes do Inno Setup no valor, se precisar, para usar
caminhos de pastas ou arquivos que variam de sistema para sistema - como no caso,
usei a {app} para retornar a pasta da aplicação, já que queria referenciar um arquivo
dentro dela.

Apesar de não ser necessário seguir a ordem no script do Inno para as chaves do
registro, uma organização sempre faz bem. Por experiências próprias com ele, sugiro
criar as chaves definindo que elas deverão ser removidas após a instalação, e só depois
de declarar isso, colocar as entradas que gravarão os valores propriamente ditos. Por
exemplo:

Root: HKLM; SubKey: SoftwareEmpresa; Flags: uninsdeletekeyifempty

Root: HKCU; SubKey: SoftwareEmpresa; Flags: uninsdeletekeyifempty

Root: HKLM; SubKey: SoftwareEmpresaPrograma; Flags: uninsdeletekey

Root: HKCU; SubKey: SoftwareEmpresaPrograma; Flags: uninsdeletekey

Isso supondo que você grave as configurações do seu programa na chave


HKEY_CURRENT_USER Software Empresa Programa. Caso você tenha vários
programas da mesma empresa, pode guardar as configurações dos outros numa
subchave da chave da empresa, que serão vistos pelo editor do registro do Windows
como pastinhas:

Seguindo a forma exemplificada nas 4 linhas mais acima, você obtém um instalador
mais "profissional". Ele cria a chave para a empresa, se ainda não existir, e configura
para removê-la na desinstalação apenas se estiver vazia (com o uso da flag
uninsdeletekeyifempty). Após isso, cria a chave do programa, dentro da chave da
empresa, e configura para remoção na desinstalação, mesmo se não estiver vazia (já que
está removendo o programa, não teria porque manter a chave do registro dele). A flag
uninsdeletekey faz com que a chave e todas as suas subchaves sejam removidas na
desinstalação. Caso você tenha vários programas, eles nunca removerão as
configurações dos outros, pois cada um terá sua própria chave, sob o nome da chave da
empresa. Ao desinstalar o último programa desta empresa, é que a chave da empresa
será removida. Antes disso, não, pois com o uso da flag uninsdeletekeyifempty para a
chave da empresa, esta não será excluída se ainda existirem subchaves (provavelmente
de seus outros programas). Uma dica é colocar na ordem exibida. Na desinstalação, o
Inno Setup executa as funções correspondentes de baixo para cima no script, as
primeiras entradas serão as últimas a serem tratadas na desinstalação.

Caso você não queira usar uma chave para a empresa (que pode ser o seu nome, o
produtor do programa), pode então usar diretamente uma para o programa, ficando
assim apenas:

Root: HKLM; SubKey: SoftwarePrograma; Flags: uninsdeletekey

Root: HKCU; SubKey: SoftwarePrograma; Flags: uninsdeletekey


Nota: exemplifiquei com o uso do mesmo caminho de chave sob a
HKEY_LOCAL_MACHINE e HKEY_CURRENT_USER. Para guardar as
configurações do usuário, sempre prefira a HKEY_CURRENT_USER, use a
HKEY_LOCAL_MACHINE para guardar dados durante a instalação que deverão estar
acessíveis para leitura por todos os usuários.

Nunca use o uninsdeletekey em chaves usadas por outros programas ou pelo Windows.
E a definição das chaves que seu programa usará deve ser feita no projeto do programa,
não apenas na hora da criação do instalador. Se seu programa irá criar novas chaves em
outros locais depois de aberto, é uma boa incluí-las para remoção, bastando definir da
forma acima, como se fosse criá-las, e usar as flags uninsdeletekey ou
uninsdeletekeyifempty, dependendo da situação.

Associando arquivos ao seu programa

Um uso comum da seção [Registry] é a associação de arquivos ao seu programa,


embora eu prefira usar alguma função diretamente dentro do programa - por poder ser
chamada pelo usuário sem que ele precise realizar uma nova instalação. Ela pode ser
feita pela chave HKEY_CLASSES_ROOT, e a sintaxe seria:

[Registry]

Root: HKCR; Subkey: ".myp"; ValueType: string; ValueName: ""; ValueData:


"MyProgramFile"; Flags: uninsdeletevalue

Root: HKCR; Subkey: "MyProgramFile"; ValueType: string; ValueName: "";


ValueData: "My Program File"; Flags: uninsdeletekey

Root: HKCR; Subkey: "MyProgramFileDefaultIcon"; ValueType: string; ValueName:


""; ValueData: "{app}MYPROG.EXE,0"

Root: HKCR; Subkey: "MyProgramFileshellopencommand"; ValueType: string;


ValueName: ""; ValueData: """{app}MYPROG.EXE"" ""%1"""

Onde:
.myp é a extensão desejada;

MyProgramFile é o nome interno do tipo de arquivo, use um diferente para cada


extensão;

My Program File é a descrição dos arquivos desse tipo, que aparecerá no Windows
Explorer;

{app}MYPROG.EXE,0 define o ícone dos arquivos, que poderá estar em um


executável ou DLL (devendo ser seguido do índice) ou indique diretamente um arquivo
.ico;
Tome cuidado aqui: ""{app}MYPROG.EXE"" ""%1"". É desse jeito, use as aspas
duplas e duplicadas, e cuidado com o espaço antes do ""%1"". A string final deverá
ficar assim:

"C:Arquivos de programasMYPROG.EXE" "%1"

Como as aspas são usadas internamente pelo Inno, é necessário usá-las duas vezes
seguidas, "", para que sejam gravada no registro uma única aspa.

Dica: ao modificar as associações de arquivos na instalação, inclua a diretiva


ChangesAssociations=yes na seção [Setup]. Com ela, o instalador notifica o Windows
para que recarregue as configurações de associações de arquivos no Explorer ao final da
instalação.

Ao associar arquivos ao seu programa, tenha em mente que o mesmo deverá estar
programado para abrir arquivos passados como parâmetro pela linha de comando. Caso
contrário, ao dar um duplo clique num arquivo da extensão escolhida, o seu programa
até será aberto, mas sem fazer nada - sem abrir o arquivo.

Lembre-se que você pode consultar a ajuda do Inno Setup (ou a ajuda on line do Mep
Installer, que está em português) para ver as outras opções possíveis.

Execução de programas ao final da instalação ou desinstalação

Comum em muitos programas de instalação, pode ser útil rodar programas no final da
instalação ou antes da desinstalação. Para isso existem as seções [Run] e
[UninstallRun]. A sintaxe básica delas não têm segredo, e compartilham muitas
propriedades. A Run roda programas ao final da instalação, antes de concluí-la, e a
UninstallRun, antes da desinstalação começar.

Um exemplo:

[Run]

Filename: {app}Programa.exe; Parameters: /teste; StatusMsg: "Testando o programa"

A mensagem no StatusMsg é opcional, e pode ser declarada para aparecer durante a


instalação, enquanto o instalador termina. Se nada for informado, ficará a mensagem
padrão "Concluindo instalação". Com as flags você pode configurar diversas coisas,
como ocultar a janela do instalador ao rodar o comando, rodar o comando oculto (não
faça isso para programas que exijam interação do usuário, senão o instalador vai ficar
parado e o programa não seria mostrado :p), etc.

São vários os parâmetros, há uma lista na ajuda que comentei, do Mep Installer:

http://www.mephost.com/software/help/mpist14/secao_run.htm
Antes da desinstalação é a mesma coisa, use apenas dentro da [UninstallRun].

Excluindo arquivos na desinstalação ou instalação

Por padrão, o instalador do Inno Setup exclui apenas arquivos que ele tenha criado. Se
seu programa criar pastas ou arquivos depois de instalado, estes permanecerão no
sistema do usuário. Algumas vezes podem ser arquivos INI, que ficam na pasta da
aplicação (inadequado hoje em dia, visto que os usuários limitados não podem gravar
nada na pasta Arquivos de programas, mas muitos "programadores" insistem em usar
isso, em vez de guardar o INI numa pasta sob o perfil do usuário). Seja qual for o caso,
ao desinstalar seu programa a pasta dele poderá permanecer no sistema do usuário - o
que é um tanto "chato" e incômodo.

Com a seção [UninstallDelete], você pode excluir pastas ou arquivos, durante a


desinstalação. Você até pode colocar a pasta da sua aplicação, e excluir ela inteira. Mas
isso não é uma boa idéia. Simples: se o usuário instalar o programa em outro lugar, por
engano (como na pasta Documentos), ao desinstalar, a pasta toda iria pro saco. O meio
mais "correto" seria incluir na seção [UninstallDelete] apenas arquivos que você saiba
que seu programa poderá criar, e que deverão ser removidos. Exemplo:

[UninstallDelete]

Type: files; Name: {app}Programa.ini

Type: files; Name: {app}teste.txt

Type: filesandordirs; Name: {app}temporarios

Defina files no parâmetro Type para excluir arquivos, e filesandordirs para excluir
arquivos ou pastas (incluindo subpastas e tudo o que existir dentro delas).

Em outras situações, pode ser necessário remover algum arquivo durante a instalação.
Um exemplo é quando uma nova versão do seu programa não usa mais um arquivo que
uma versão anterior usava. Seria bom removê-lo :)

Basta usar a [InstallDelete], e a sintaxe das entradas se mantém a mesma da


[UninstallDelete].

Protegendo e criptografando o instalador com uma senha

O Inno Setup pode proteger a instalação com uma senha, é uma medida de "segurança"
básica. A senha não é a mesma coisa de um número serial, apesar de ter função
parecida: sem ela, não será possível continuar a instalação. É simples, basta definir a
diretiva Password na seção [Setup]:

Password=teste
A tela que pede a senha para o usuário será assim:

A senha não será gravada no arquivo diretamente, mas sim um hash (sombra) dela. Os
arquivos, o conteúdo do instalador em si, não estarão "protegidos": eles não são
encriptados por padrão. Você pode forçar uma encriptação usando a diretiva
Encryption, ativando-a com "yes" na seção [Setup]:

Password=teste
Encryption=yes

Para isso, uma DLL com a função de criptografia do Inno deverá ser colocada na pasta
do Inno Setup. Ele não inclui o suporte "nativo" à criptografia devido a legislação de
alguns países. Basta baixar a DLL em:

http://www.jrsoftware.org/isdl.php

E colocá-la na pasta do Inno (normalmente Arquivos de programas Inno Setup). Não se


preocupe em redistribui-la com o seu programa, não será necessário. Com a criptografia
ativada, o conteúdo do instalador será codificado usando como base a senha escolhida, e
então o arquivo estará protegido (mesmo que alguém consiga acesso ao pacote de dados
dentro do instalador - o que não é difícil, visto que o Inno Setup é open source - não
poderá fazer nada com os arquivos, pois estarão criptografados).

Protegendo com um número serial

A proteção por número serial é um recurso possível no Inno Setup, mas não
"diretamente". Com a diretiva UserInfoPage=yes na seção [Setup], ele mostra uma tela
para digitação de um nome de usuário e organização. Mas não um número serial. O
nome e a organização poderão ser recuperados com as constantes {userinfoname} e
{userinfoorg}, podendo ser gravados no registro, num arquivo INI ou então passados
como parâmetro para algum programa (usando a seção [Run], deixando a constante
{userinfoname} ou {userinfoorg} como parâmetro para o seu executável).

Para que apareça o campo de número serial, você deverá usar a seção [Code]. O Inno
Setup, a partir da versão 4, permite a codificação usando o Pascal Script. É uma
linguagem de script baseada em Pascal, muito parecida com o Delphi. Você pode
"programar" dentro do Inno, executar funções personalizadas em algumas situações e
inclusive chamar funções em DLLs - suas ou não.

A seção [Code] é um pouco complexa para entender de imediato, ela contém funções e
rotinas próprias que se aplicam apenas ao Inno Setup, assim como contém funções
comuns a outros ambientes (principalmente ao Delphi; a saber, o Inno Setup é feito em
Delphi). Para verificação de número serial, você deve criar a seção [Code] no script do
Inno, e colocar a função CheckSerial. Esta função tem esta sintaxe:

function CheckSerial(Serial: String): Boolean;

O que ela faz? Ela recebe o serial preenchido pelo usuário, que é passado como string, e
deve devolver um valor booleano (sim ou não), para liberar ou não a instalação. Para
implementá-la, coloque no final do arquivo de script do Inno Setup:

[Code]

function CheckSerial(Serial: String): Boolean;

begin
end;

Entre o begin e o end você pode fazer literalmente o que quiser, como se estivesse num
ambiente de programação. As funções internas providas com o Inno Setup são básicas,
mas você poderá chamar DLLs, como explico já já.

Para validar o serial rapidamente, você poderia colocar:

function CheckSerial(Serial: String): Boolean;

begin
if Serial = '123456' then

Result := True

else
Result := False;

end;
Isso limita a instalação ao serial "123456". Experimente compilar o instalador e testar :)

Não se esqueça de ativar a tela de informações do usuário, colocando


UserInfoPage=yes, na seção [Setup].

Se você quiser, pode implementar um pouco mais, e testar também o nome de usuário e
a organização preenchidos. Para isso, precisará usar variáveis e a função
ExpandConstant, que expande uma constante do Inno, retornando o valor dela como
string:

function CheckSerial(Serial: String): Boolean;

var

usu, org: String;

begin
usu := ExpandConstant('{userinfoname}');

org := ExpandConstant('{userinfoorg}');

if (usu = 'Marcos') and (org = 'Guia do Hardware') and (Serial = '123456') then

Result := True

else
Result := False;
end;

Coloquei assim por motivos didáticos, nada impede que você simplifique a verificação
do if, deixando-o apenas assim:

Result := (usu = 'Marcos') and (org = 'Guia do Hardware') and (Serial = '123456');

Uma observação importante no Inno Setup, é que esta função é chamada para cada
caractere que o usuário digitar. Se você inventar algum algoritmo de verificação
diabólico que coma muito processamento, a digitação do serial pelo usuário ficará
"lenta". Ele chama a função ao digitar, pois libera o botão "Avançar" apenas se a
informação estiver correta. Enquanto a função CheckSerial retornar False, o botão
Avançar fica desativado.

Nada impede que algum "hacker" manipule o estado do botão Next do Inno Setup,
usando aplicações de terceiros, e parta para a próxima tela sem digitar o número serial.
O recurso é interessante, mas deve ser usado com cuidado. O Inno é um projeto aberto,
suas especificações são claras e qualquer um munido de conhecimentos avançados pode
manipular a função CheckSerial para sempre retornar True. A recomendação seria usar
um sistema de registro externo ao Inno, com um algoritmo criado por você, e talvez usar
o campo de serial apenas para a inserção do serial e posterior processamento - algo que
pode ser útil dado o visual do instalador, ficaria mais "tradicional" solicitar o número
serial durante a instalação. Uma proteção maior pode se dar usando a senha com
criptografia ativada, como comentado mais acima - onde mesmo se o "hacker" burlar o
sistema e conseguir avançar, os arquivos estarão altamente corrompidos sem a senha
certa, e não servirão para nada.

Integração com DLLs: um exemplo prático

Uma das grandes vantagens do Inno Setup é a liberdade de programação. Com o Pascal
Script, você pode usar uma série de funções para fazer uma infinidade de coisas. As
funções inclusas com o Inno constam na ajuda dele, vale a pena dar uma conferida. E
para as que não estão, você pode usar funções de DLLs, sejam estas suas ou não.

Vou dar um exemplo ainda na função CheckSerial, onde o algoritmo de verificação do


número serial fica numa DLL. Há outras funções do Inno que são executadas em outras
situações, como ao avançar nas telas de instalação, ao iniciar o instalador, ao finalizá-lo,
ao copiar arquivos, etc.

Para usar funções de DLL, você precisa declará-las, assim:

function ValidaReg(usu, org, serial: String): Boolean;

external 'ValidaReg@files:CheckSerial.dll stdcall';

O primeiro nome ValidaReg escolhido pode ser um nome qualquer, será o nome da
função importada dentro do programa - dentro do instalador. Ela receberá três
parâmetros: o nome do usuário, organização e número serial preenchidos. E deverá
retornar um valor booleano, True para liberar a instalação, ou False para negá-la.

Na segunda linha, fica indicado que a ValidaReg está na DLL CheckSerial.dll (que
poderia ser qualquer outra). Mas onde estará esta DLL no sistema do usuário?

Você deve incluí-la no instalador, na seção [Files], com a flag especial dontcopy:

[Files]

...

Source: "CheckSerial.dll"; Flags: dontcopy

Essa flag faz que o arquivo indicado não seja copiado para a pasta da aplicação. Ele
ficará numa pasta temporária que o Inno Setup cria durante a instalação, e a remove
assim que a instalação é concluída.

Declarada a função da DLL, você pode usá-la no código da seção [Code], como se fosse
uma função nativa do Inno. No caso da verificação do número serial, mudaríamos o
código para isso:

function CheckSerial(Serial: String): Boolean;

var

usu, org: String;

begin
usu := ExpandConstant('{userinfoname}');

org := ExpandConstant('{userinfoorg}');

Result := ValidaReg(usu,org,Serial);

end;

Ou seja, quem determinará o resultado (True ou False) deixa de ser um verificador


diretamente nesta função, sendo a função ValidaReg na DLL. Aqui está um exemplo da
integração do Inno Setup com uma DLL. A criação de DLLs foge ao objetivo deste
artigo, mas para que possa ser concluído, você precisará criar uma DLL de exemplo.

Em Delphi, você poderia simplesmente criar um arquivo .dpr com este conteúdo, e
compilá-lo, que já teria a DLL que exporta a função ValidaReg:

library CheckSerial;

uses

Windows;
function ValidaReg(usu, org, serial: String): Boolean; stdcall;
begin
if (usu='Marcos') and (org='Mep') and (serial='123-456-789') then

Result := True

else
Result := False;

end;
exports ValidaReg;

begin
end.

Dentro da DLL você pode programar como quiser, aí fica a seu critério. A validação do
número serial deve usar algum algoritmo criado por você, e claro, com algum sistema
gerador de seriais com base no nome de usuário que só você possua. Não se esqueça
que as DLLs interagem com os arquivos independentemente da linguagem em que
foram criados (Delphi, C++, VB, etc), já que elas são compiladas.

A integração com DLLs do Inno Setup é muito boa e estável, e permite que ele dê conta
de coisas que muitos instaladores comerciais não fazem.

Concluindo

Eis um pouco do Inno Setup. Ele ainda pode ser personalizado, de várias formas: além
do uso de DLLs, é possível adicionar páginas (telas de instalação) personalizadas, para
obter dados adicionais do usuário durante a instalação. Ou você pode ir mais longe,
baixando o código fonte do Inno e alterando diretamente os arquivos do instalador - o
que não é fácil, mas pode ser uma experiência interessante. Ele foi feito em Borland
Delphi, e é compilado pelo Jordan Russell no velho Delphi 2 - já que as versões antigas
do Delphi geram executáveis bem pequenos, perto das versões recentes ;)

Se você não gosta de manipular o script diretamente, pode experimentar o ISTool, uma
interface gráfica para o Inno Setup, que permite criar e modificar os arquivos .iss
facilmente:
Ele e várias outras utilidades podem ser baixados na página de downloads do Inno:

http://www.jrsoftware.org/is3rdparty.php

Bom trabalho :)