Configurações Avançadas do InnoSetup para Instaladores Windows

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;

Tags: InnoSetup Windows Installer Registry Environment Variables Windows Services

Publicado em 6-28 22:57