Depuração do instalador do Inno Setup que se reinicia

Dec 21 2020

Como pode ser visto a partir desta questão, iniciamos uma nova instância do Inno Setup:

Instance := ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);

Onde

function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
      lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
      external '[email protected] stdcall';

Todo o código da resposta desta pergunta eu movi para o VCL_Styles.issarquivo e incluí em meu script principal.

O problema é que depois de passar a ShellExecutechamada e encerrar pelo depurador, uma instância do Inno Setup continua em execução (então tenho que interromper o processo usando o Gerenciador de Tarefas do Windows) e recebo as seguintes mensagens no Debug Output:

*** Processo de rescisão

*** Removendo o diretório temporário restante: C: \ Users \ JCONST ~ 1 \ AppData \ Local \ Temp \ is-PV9OS.tmp

*** A instalação ainda está em execução; não consigo obter o código de saída

em vez do código de saída 6 que de acordo com a documentação é retornado quando:

O processo de instalação foi encerrado à força pelo depurador (Run | Terminate foi usado no Compiler IDE).

Não tenho certeza de qual instância do Inno Setup ainda está em execução e como posso interrompê-la?

Aqui está o conteúdo do VCL.Stylesque incluo em meu script principal, então recebo o erro mencionado:

[Setup]
ShowLanguageDialog=no

[Code]
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
  lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
  external '[email protected] stdcall';

<event('InitializeSetup')>
function MyInitializeSetup2: Boolean;
var
  Instance: THandle;
  I: Integer;
  S, Params, Language: String;
begin
  Result := True;

  for I := 1 to ParamCount do
    begin
      S := ParamStr(I);
      if CompareText(Copy(S, 1, 5), '/SL5=') <> 0 then
      begin
        Params := Params + AddQuotes(S) + ' ';
      end;
    end;

  Params := Params + '/LANG=en';
  Language := ExpandConstant('{param:LANG}');
  if Language = '' then
    begin
      Instance := ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
      if Instance <= 32 then
        begin
          S := 'Running installer with the selected language failed. Code: %d';
          MsgBox(Format(S, [Instance]), mbError, MB_OK);
        end;
      Result := False;
      Exit;
    end;
end;

Respostas

1 MartinPrikryl Dec 28 2020 at 14:51

Quando o depurador passa por cima do ShellExecutee a nova instância do processo do instalador é iniciada, o depurador IDE parece selecionar esse processo e reiniciar a depuração. Presumo que esse não seja um comportamento intencional, ou pelo menos não seja um comportamento bem testado. A função Terminate então provavelmente tenta fechar / se comunicar com o processo antigo (que foi encerrado por conta própria entretanto - devido ao seu InitializeSetupretorno Falseapós o ShellExecute).

Martijn Laan (o atual mantenedor do Inno Setup) afirmou que o Inno Setup não foi projetado para reaparecer sozinho. Na verdade, a própria ExecAPI do Inno Setup evita explicitamente a restauração do instalador. Ignorar essa restrição usando WinAPI, ShellExecuteem vez disso, apresenta o problema descrito na pergunta. Não é surpresa que o depurador não consiga lidar com essa situação.

JConstantine Dec 21 2020 at 21:46

Parece que um bug do IDE do Inno Setup pode ter causado esse problema.

Este é o link do relatório:

https://groups.google.com/g/innosetup/c/pDSbgD8nbxI/m/0lvTsslOAwAJ