Men-debug penginstal Inno Setup yang muncul kembali sendiri

Dec 21 2020

Seperti yang dapat dilihat dari pertanyaan ini , kami memulai contoh baru Inno Setup:

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

dimana

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

Semua kode dari ini jawaban pertanyaan ini saya pindah ke VCL_Styles.issberkas dan termasuk ke dalam naskah utama saya.

Masalahnya adalah setelah saya melewati ShellExecutepanggilan dan diakhiri oleh debugger setelah itu satu instance Inno Setup terus berjalan (jadi saya harus mematikan proses menggunakan Windows Task Manager) dan saya mendapatkan pesan berikut di Debug Output:

*** Proses penghentian

*** Menghapus direktori sementara yang tersisa: C:\Users\JCONST~1\AppData\Local\Temp\is-PV9OS.tmp

*** Pengaturan masih berjalan; tidak bisa mendapatkan kode keluar

alih-alih kode keluar 6 yang menurut dokumentasi dikembalikan ketika:

Proses Setup secara paksa dihentikan oleh debugger (Run | Terminate digunakan di Compiler IDE).

Saya tidak yakin instance Inno Setup mana yang masih berjalan dan bagaimana cara menghentikannya?

Inilah konten VCL.Stylesyang saya sertakan ke dalam skrip utama saya sehingga saya mendapatkan kesalahan yang disebutkan di atas:

[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;

Jawaban

1 MartinPrikryl Dec 28 2020 at 14:51

Ketika debugger melangkahi ShellExecutedan contoh baru dari proses penginstal dimulai, debugger IDE tampaknya memilih proses itu dan memulai kembali proses debug. Saya berasumsi ini bukan perilaku yang dimaksudkan, atau setidaknya bukan perilaku yang teruji dengan baik. Fungsi Terminate kemudian mungkin mencoba untuk menutup/berkomunikasi dengan proses lama (yang telah dihentikan dengan sendirinya - karena InitializeSetupkembali Falsesetelah ShellExecute).

Martijn Laan (pengelola Inno Setup saat ini) menyatakan bahwa Inno Setup tidak dirancang untuk respawn sendiri. Sebenarnya Inno Setup ExecAPI sendiri secara eksplisit mencegah respawning installer. Melewati batasan ini dengan menggunakan WinAPI ShellExecutemalah menimbulkan masalah yang dijelaskan dalam pertanyaan. Tidak mengherankan bahwa debugger tidak dapat menangani situasi ini.

JConstantine Dec 21 2020 at 21:46

Sepertinya bug IDE Inno Setup mungkin menyebabkan masalah itu.

Berikut link laporannya:

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