Отладка инсталлятора Inno Setup, который возрождается
Как видно из этого вопроса, мы запускаем новый экземпляр Inno Setup:
Instance := ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
где
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
external '[email protected] stdcall';
Весь код из ответа на этот вопрос я переместил в VCL_Styles.iss
файл и включил в свой основной скрипт.
Проблема в том, что после того, как я передал ShellExecute
вызов и завершил работу отладчиком, один экземпляр Inno Setup продолжает работать (поэтому мне нужно убить процесс с помощью диспетчера задач Windows), и я получаю следующие сообщения в Debug Output
:
*** Завершение процесса
*** Удаление оставшегося временного каталога: C: \ Users \ JCONST ~ 1 \ AppData \ Local \ Temp \ is-PV9OS.tmp
*** Установка все еще продолжается; не могу получить код выхода
вместо кода выхода 6, который, согласно документации , возвращается, когда:
Процесс установки был принудительно прерван отладчиком (в среде Compiler IDE использовалось Run | Terminate).
Я не уверен, какой экземпляр Inno Setup все еще работает и как его остановить?
Вот содержимое того, VCL.Styles
что я включаю в свой основной скрипт, поэтому я получаю вышеупомянутую ошибку:
[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;
Ответы
Когда отладчик переходит ShellExecute
и запускается новый экземпляр процесса установщика, отладчик IDE, кажется, выбирает этот процесс и перезапускает отладку. Я предполагаю, что это ненамеренное поведение или, по крайней мере, не проверенное. Затем функция Terminate, вероятно, пытается закрыть / связаться со старым процессом (который тем временем завершился сам по себе - из-за его InitializeSetup
возврата False
после ShellExecute
).
Мартейн Лаан (текущий сопровождающий Inno Setup) заявил, что Inno Setup не предназначен для самопроизвольного возрождения. На самом деле собственный Exec
API Inno Setup явно предотвращает повторное создание установщика. Обход этого ограничения с помощью WinAPI ShellExecute
вместо этого создает проблему, описанную в вопросе. Неудивительно, что отладчик не может справиться с этой ситуацией.
Похоже, что ошибка IDE Inno Setup могла вызвать эту проблему.
Вот ссылка на отчет:
https://groups.google.com/g/innosetup/c/pDSbgD8nbxI/m/0lvTsslOAwAJ