Men-debug penginstal Inno Setup yang muncul kembali sendiri
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.iss
berkas dan termasuk ke dalam naskah utama saya.
Masalahnya adalah setelah saya melewati ShellExecute
panggilan 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.Styles
yang 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
Ketika debugger melangkahi ShellExecute
dan 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 InitializeSetup
kembali False
setelah ShellExecute
).
Martijn Laan (pengelola Inno Setup saat ini) menyatakan bahwa Inno Setup tidak dirancang untuk respawn sendiri. Sebenarnya Inno Setup Exec
API sendiri secara eksplisit mencegah respawning installer. Melewati batasan ini dengan menggunakan WinAPI ShellExecute
malah menimbulkan masalah yang dijelaskan dalam pertanyaan. Tidak mengherankan bahwa debugger tidak dapat menangani situasi ini.
Sepertinya bug IDE Inno Setup mungkin menyebabkan masalah itu.
Berikut link laporannya:
https://groups.google.com/g/innosetup/c/pDSbgD8nbxI/m/0lvTsslOAwAJ