Отладка инсталлятора Inno Setup, который возрождается

Dec 21 2020

Как видно из этого вопроса, мы запускаем новый экземпляр 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;

Ответы

1 MartinPrikryl Dec 28 2020 at 14:51

Когда отладчик переходит ShellExecuteи запускается новый экземпляр процесса установщика, отладчик IDE, кажется, выбирает этот процесс и перезапускает отладку. Я предполагаю, что это ненамеренное поведение или, по крайней мере, не проверенное. Затем функция Terminate, вероятно, пытается закрыть / связаться со старым процессом (который тем временем завершился сам по себе - из-за его InitializeSetupвозврата Falseпосле ShellExecute).

Мартейн Лаан (текущий сопровождающий Inno Setup) заявил, что Inno Setup не предназначен для самопроизвольного возрождения. На самом деле собственный ExecAPI Inno Setup явно предотвращает повторное создание установщика. Обход этого ограничения с помощью WinAPI ShellExecuteвместо этого создает проблему, описанную в вопросе. Неудивительно, что отладчик не может справиться с этой ситуацией.

JConstantine Dec 21 2020 at 21:46

Похоже, что ошибка IDE Inno Setup могла вызвать эту проблему.

Вот ссылка на отчет:

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