Depuração do instalador do Inno Setup que se reinicia
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.iss
arquivo e incluí em meu script principal.
O problema é que depois de passar a ShellExecute
chamada 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.Styles
que 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
Quando o depurador passa por cima do ShellExecute
e 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 InitializeSetup
retorno False
apó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 Exec
API do Inno Setup evita explicitamente a restauração do instalador. Ignorar essa restrição usando WinAPI, ShellExecute
em vez disso, apresenta o problema descrito na pergunta. Não é surpresa que o depurador não consiga lidar com essa situação.
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