Débogage du programme d'installation d'Inno Setup qui se régénère

Dec 21 2020

Comme on peut le voir à partir de cette question, nous commençons une nouvelle instance d'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';

Tout le code de la réponse à cette question, j'ai déplacé vers le VCL_Styles.issfichier et je l'ai inclus dans mon script principal.

Le problème est qu'après avoir passé l' ShellExecuteappel et terminé par le débogueur, une instance d'Inno Setup continue de s'exécuter (je dois donc tuer le processus à l'aide du Gestionnaire des tâches de Windows) et j'obtiens les messages suivants dans le Debug Output:

*** Processus de résiliation

*** Suppression du répertoire temporaire restant : C:\Users\JCONST~1\AppData\Local\Temp\is-PV9OS.tmp

*** Le programme d'installation est toujours en cours d'exécution ; impossible d'obtenir le code de sortie

au lieu du code de sortie 6 qui selon la documentation est retourné quand :

Le processus d'installation a été interrompu de force par le débogueur (Exécuter | Terminer a été utilisé dans l'IDE du compilateur).

Je ne sais pas quelle instance d'Inno Setup est toujours en cours d'exécution et comment puis-je l'arrêter ?

Voici le contenu du VCL.Stylesque j'inclus dans mon script principal afin que j'obtienne l'erreur susmentionnée :

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

Réponses

1 MartinPrikryl Dec 28 2020 at 14:51

Lorsque le débogueur franchit le pas ShellExecuteet que la nouvelle instance du processus d'installation est démarrée, le débogueur IDE semble sélectionner ce processus et redémarrer le débogage. Je suppose que ce n'est pas un comportement intentionnel, ou du moins pas un comportement bien testé. La fonction Terminate essaie alors probablement de se fermer/communiquer avec l'ancien processus (qui s'est terminé tout seul entre-temps - en raison de son InitializeSetupretour Falseaprès le ShellExecute).

Martijn Laan (le mainteneur actuel d'Inno Setup) a déclaré qu'Inno Setup n'est pas conçu pour réapparaître de lui-même. En fait, la propre ExecAPI d' Inno Setup empêche explicitement la réapparition du programme d'installation. Le contournement de cette restriction en utilisant WinAPI ShellExecuteintroduit à la place le problème décrit dans la question. Ce n'est pas une surprise que le débogueur ne puisse pas gérer cette situation.

JConstantine Dec 21 2020 at 21:46

On dirait qu'un bogue IDE d'Inno Setup peut avoir causé ce problème.

Voici le lien du rapport :

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