Criando Entradas no Registro do Windows
A seção [Registry] permite manipular diretamente o registro do Windows durante a instalação. Veja um exemplo de como registrar um protocolo personalizado:
[Registry]
Root: HKLM; Subkey: "SOFTWARE\MyAppProtocol"; ValueType: string; ValueData: "URL:MyApp Protocol"; Flags: uninsdeletekey
Parâmetro Root
Define a raiz do registro. Valores aceitos:
HKCR -> HKEY_CLASSES_ROOT
HKCU -> HKEY_CURRENT_USER
HKLM -> HKEY_LOCAL_MACHINE
HKU -> HKEY_USERS
HKCC -> HKEY_CURRENT_CONFIG
Parâmetro Subkey
Caminho da subchave dentro do registro. Suporta constantes do InnoSetup.
Parâmetro ValueType
Especifica o tipo de dado a ser armazenado. Opções disponíveis:
- none — Cria apenas a chave sem valor associado (padrão)
- string — Valor de texto simples (REG_SZ)
- expandsz — Texto com variáveis expansíveis (REG_EXPAND_SZ)
- multisz — Texto em múltiplas linhas (REG_MULTI_SZ)
- dword — Número inteiro de 32 bits (REG_DWORD)
- qword — Número inteiro de 64 bits (REG_QWORD)
- binary — Dados binários (REG_BINARY)
Parâmetro Flags
Opções adicionais que podem ser combinadas com espaços:
- createvalueifdoesntexist — Cria o valor somente se não existir previamente
- deletekey — Remove a chave inteira antes de criar uma nova
- deletevalue — Remove o valor existente antes de criar um novo
- dontcreatekey — Não cria a chave se ela não existir no sistema
- noerror — Suprime mensagens de erro durante operações no registro
- preservestringtype — Mantém o tipo original se o valor já for string
- uninsclearvalue — Limpa o valor durante a desinstalação
- uninsdeletekey — Remove toda a chave durante a deisnstalação
- uninsdeletekeyifempty — Remove a chave apenas se estiver vazia na desinstalação
- uninsdeletevalue — Remove o valor específico durante a desinstalação
Gerenciando Variáveis de Ambiente via Script
Para adicionar variáveis de ambiente de forma programática, utilize o evento CurStepChanged:
procedure CurStepChanged(Step: TSetupStep);
var
currentPath: string;
updatedPath: string;
javaInstallDir: string;
begin
if Step = ssPostInstall then
begin
javaInstallDir := ExpandConstant('{app}\jdk');
RegQueryStringValue(HKLM,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', currentPath);
updatedPath := currentPath + ';' + javaInstallDir + '\bin';
RegWriteStringValue(HKLM,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'PATH', updatedPath);
RegWriteStringValue(HKLM,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'JAVA_HOME', javaInstallDir);
end;
end;
É essencial adicionar ChangesEnvironment=yes na seção [Setup] para que outras aplicações detectem as alterações nas variáveis de ambiente.
Removendo Variáveis de Ambiente na Desinstalação
Para limpar as variáveis criadas durente a instalação, implemente o handler CurUninstallStepChanged:
procedure CurUninstallStepChanged(Step: TUninstallStep);
var
pathValue: string;
cleanedPath: string;
javaDir: string;
begin
if Step = usDone then
begin
javaDir := ExpandConstant('{app}\jdk');
RegDeleteValue(HKLM,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'JAVA_HOME');
RegQueryStringValue(HKLM,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'Path', pathValue);
StringChangeEx(pathValue, ';' + javaDir + '\bin', '', True);
cleanedPath := pathValue;
RegWriteStringValue(HKLM,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
'PATH', cleanedPath);
end;
end;
Executando Cmoandos Pós-Instalação
A seção [Run] permite executar programas após a conclusão da instalação:
[Run]
Filename: "{app}\scripts\init-service.bat"; \
Description: "Inicializar serviço"; \
Flags: shellexec postinstall waituntilterminated runascurrentuser
Flags do [Run]
Principais opções disponíveis:
- 32bit / 64bit — Define se {sys} aponta para o diretório System de 32 ou 64 bits
- hidewizard — Oculta o assistente durante a execução do programa
- nowait — Não aguarda o término do processo
- postinstall — Exibe checkbox na página final para o usuário decidir
- runascurrentuser — Executa com as credenciais do instalador
- runasoriginaluser — Executa com as credenciais do usuário original
- runhidden — Executa em janela oculta
- runmaximized — Executa em janela maximizada
- runminimized — Executa em janela minimizada
- shellexec — Necessário para arquivos não-executáveis (.bat, .doc, etc)
- skipifdoesntexist — Ignora silenciosamente se o arquivo não existir
- skipifnotsilent — Pula se a instalação não for silenciosa
- skipifsilent — Pula se a instalação for silenciosa
- unchecked — Checkbox inicialmente desmarcado
- waituntilidle — Aguarda até o processo entrar em estado ocioso
- waituntilterminated — Aguarda o término completo do processo
Removendo Versão Anterior Automaticamente
Para desinstalar uma versão existente antes de prosseguir com a nova instalação:
function InitializeSetup(): Boolean;
var
uninstallerPath: string;
execResult: Boolean;
exitCode: Integer;
begin
if RegQueryStringValue(HKLM,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1',
'UninstallString', uninstallerPath) then
begin
if MsgBox('Versão anterior detectada. Deseja removê-la?',
mbConfirmation, MB_YESNO) = IDNO then
begin
Result := False;
Exit;
end;
uninstallerPath := RemoveQuotes(uninstallerPath);
execResult := Exec(uninstallerPath, '/VERYSILENT', '',
SW_HIDE, ewWaitUntilTerminated, exitCode);
if not execResult or (exitCode <> 0) then
begin
MsgBox('Falha ao remover versão anterior!', mbError, MB_OK);
Result := False;
Exit;
end;
end;
Result := True;
end;
Verificando e Removendo Serviços do Windows
Para detectar a existência de um serviço e removê-lo antes da instalação:
function RemoveWindowsService(serviceName: String): Boolean;
var
errCode: Integer;
shellResult: Boolean;
queryCmd: string;
removeCmd: string;
begin
queryCmd := Format('/c sc query "%s"', [serviceName]);
removeCmd := Format('/c sc stop "%s" && sc delete "%s"', [serviceName, serviceName]);
shellResult := ShellExec('open', ExpandConstant('{cmd}'),
queryCmd, '', SW_HIDE, ewWaitUntilTerminated, errCode);
if shellResult and (errCode = 0) then
begin
if MsgBox('O serviço ' + serviceName + ' foi encontrado. Remover agora?',
mbConfirmation, MB_YESNO) = IDYES then
begin
shellResult := ShellExec('open', ExpandConstant('{cmd}'),
removeCmd, '', SW_HIDE, ewWaitUntilTerminated, errCode);
if shellResult and (errCode = 0) then
begin
MsgBox('Serviço removido com sucesso!', mbInformation, MB_OK);
Result := True;
Exit;
end
else
begin
MsgBox('Falha ao remover o serviço. Remova manualmente.', mbError, MB_OK);
Result := False;
Exit;
end;
end
else
begin
Result := False;
Exit;
end;
end;
Result := True;
end;