Debuggen des Inno Setup-Installationsprogramms, das sich selbst neu startet

Dec 21 2020

Wie aus dieser Frage ersichtlich, starten wir eine neue Instanz von Inno Setup:

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

wo

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

Den gesamten Code aus der Antwort dieser Frage habe ich in die VCL_Styles.issDatei verschoben und in mein Hauptskript aufgenommen.

Das Problem ist, dass nachdem ich den ShellExecuteAufruf übergeben und anschließend vom Debugger beendet habe, eine Instanz von Inno Setup weiterläuft (also muss ich den Prozess mit dem Windows Task-Manager beenden) und ich die folgenden Meldungen in der Debug Output:

*** Prozess beenden

*** Entfernen des übrig gebliebenen temporären Verzeichnisses: C:\Users\JCONST~1\AppData\Local\Temp\is-PV9OS.tmp

*** Setup läuft noch; kann den Exit-Code nicht abrufen

anstelle des Exitcodes 6, der laut Dokumentation zurückgegeben wird, wenn:

Der Setup-Vorgang wurde vom Debugger zwangsweise beendet (Run | Terminate wurde in der Compiler-IDE verwendet).

Ich bin mir nicht sicher, welche Instanz von Inno Setup noch ausgeführt wird und wie kann ich sie stoppen?

Hier ist der Inhalt des, den VCL.Stylesich in mein Hauptskript einfüge, damit ich den oben genannten Fehler erhalte:

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

Antworten

1 MartinPrikryl Dec 28 2020 at 14:51

Wenn der Debugger den Schritt überspringt ShellExecuteund die neue Instanz des Installationsprogramms gestartet wird, scheint der IDE-Debugger diesen Prozess auszuwählen und startet das Debuggen neu. Ich gehe davon aus, dass dies kein beabsichtigtes Verhalten ist, oder zumindest kein gut getestetes. Die Terminate- Funktion versucht dann wahrscheinlich, den alten Prozess (der inzwischen von selbst beendet wurde – aufgrund seiner InitializeSetupRückkehr Falsenach dem ShellExecute) zu schließen/mit dem alten Prozess zu kommunizieren .

Martijn Laan (der derzeitige Betreuer von Inno Setup) erklärte, dass Inno Setup nicht dazu gedacht ist, sich selbst wiederzubeleben. Tatsächlich Execverhindert die eigene API von Inno Setup explizit das Respawnen des Installers. Das Umgehen dieser Einschränkung mithilfe von WinAPI führt ShellExecutestattdessen zu dem in der Frage beschriebenen Problem. Es ist keine Überraschung, dass der Debugger diese Situation nicht bewältigen kann.

JConstantine Dec 21 2020 at 21:46

Es sieht so aus, als ob ein IDE-Fehler eines Inno Setups dieses Problem verursacht haben könnte.

Hier ist der Bericht-Link:

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