96 votes

Inno Setup : Comment désinstaller automatiquement la version précédemment installée ?

J'utilise Inno Setup pour créer un programme d'installation.

Je veux que le programme d'installation désinstalle automatiquement la version installée précédemment, au lieu de l'écraser. Comment puis-je faire cela ?

2 votes

Notez que comme mlaan a déclaré il n'est normalement pas nécessaire de le faire avec une installation basée sur Inno, à moins que vous ne mettiez à niveau une version non Inno.

7 votes

Deanna : cela dépend des cas. Pour certains programmes avec des systèmes de plugins automatiques, qui lisent tout ce qui se trouve dans un dossier, la suppression des anciens fichiers est une nécessité absolue lors de l'installation d'une nouvelle version, et le simple fait d'exécuter la désinstallation est généralement le moyen le plus propre de le faire.

1 votes

@Nyerguds Mais InnoSetup s'occupe de cela en ayant une option pour supprimer certains fichiers/dossiers avant que l'installation ne commence (drapeau "InstallDelete") donc vous n'auriez pas besoin de désinstaller l'ancienne version d'abord.

119voto

Craig McQueen Points 13194

J'ai utilisé la méthode suivante. Je ne suis pas sûr que ce soit la façon la plus simple de procéder, mais cela fonctionne.

Cela utilise {#emit SetupSetting("AppId")} qui s'appuie sur le préprocesseur Inno Setup. Si vous ne l'utilisez pas, copiez et collez votre App ID directement.

[Code]

{ ///////////////////////////////////////////////////////////////////// }
function GetUninstallString(): String;
var
  sUnInstPath: String;
  sUnInstallString: String;
begin
  sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  sUnInstallString := '';
  if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
    RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  Result := sUnInstallString;
end;

{ ///////////////////////////////////////////////////////////////////// }
function IsUpgrade(): Boolean;
begin
  Result := (GetUninstallString() <> '');
end;

{ ///////////////////////////////////////////////////////////////////// }
function UnInstallOldVersion(): Integer;
var
  sUnInstallString: String;
  iResultCode: Integer;
begin
{ Return Values: }
{ 1 - uninstall string is empty }
{ 2 - error executing the UnInstallString }
{ 3 - successfully executed the UnInstallString }

  { default return value }
  Result := 0;

  { get the uninstall string of the old app }
  sUnInstallString := GetUninstallString();
  if sUnInstallString <> '' then begin
    sUnInstallString := RemoveQuotes(sUnInstallString);
    if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
      Result := 3
    else
      Result := 2;
  end else
    Result := 1;
end;

{ ///////////////////////////////////////////////////////////////////// }
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if (CurStep=ssInstall) then
  begin
    if (IsUpgrade()) then
    begin
      UnInstallOldVersion();
    end;
  end;
end;

Alternatives

Voir aussi ce billet de blog "Inno Setup script Echantillon pour la comparaison des versions" qui va un peu plus loin, et lit le numéro de version de toute version précédemment installée, et compare ce numéro de version avec celui du paquet d'installation actuel.

3 votes

Merci de vous référer à mon article de blog. L'échantillon complet de ce billet est disponible ici, code.google.com/p/lextudio/source/browse/trunk/trunk/setup/

0 votes

La seule chose qui manque ici est le support pour une entrée de désinstallation sous HKCU au lieu de HKLM.

1 votes

Puis-je suggérer d'ajouter la possibilité de désinstaller si un utilisateur quelconque a installé l'application, en particulier si l'utilisateur actuel est un administrateur ? ... UserSIDs: TArrayOfString; I: Integer; ... if not RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString) then if isAdminLoggedOn() and RegGetSubkeyNames( HKEY_USERS, '', UserSIDs ) then for I := 0 to GetArrayLength( UserSIDs ) - 1 do begin if RegQueryStringValue( HKEY_USERS, UserSIDs[I] + '\' + sUnInstPath, 'UninstallString', sUnInstallString ) then break; end;

29voto

Oliver Giesen Points 5531

Vous devriez être capable de lire la chaîne de désinstallation à partir du registre, étant donné l'AppId (c'est-à-dire la valeur que vous avez utilisé pour AppID dans le [Setup] -). Il peut être trouvé sous Software\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\ (peut être soit HKLM ou HKCU il est donc préférable de vérifier les deux) où {AppId} doit être remplacé par la valeur réelle que vous avez utilisée. Recherchez l'icône UninstallString ou QuietUninstallString et utiliser les Exec pour l'exécuter à partir de votre InitializeSetup() fonction d'événement.

0 votes

+1, mais il faut absolument utiliser un script pour lire l'ancien nom du désinstalleur, car sinon cela ne fonctionnera pas si un chemin différent a été saisi par l'utilisateur.

3 votes

Je ne pense pas que le [Run] La solution de la section ne fonctionnera pas, car elle s'exécute trop tard dans le processus d'installation. Extrait du manuel d'Inno Setup : La section [Exécuter] est facultative et spécifie un nombre quelconque de programmes à exécuter après l'installation du programme, mais avant que le programme d'installation n'affiche la boîte de dialogue finale.

0 votes

Veuillez modifier ce message et supprimer la partie [Run], elle ne fonctionne pas. La deuxième partie fonctionne en revanche. Merci :-)

8voto

rogerdpack Points 12806

Si vous voulez "juste supprimer les anciennes icônes" (parce que les vôtres ont été modifiées/mises à jour), vous pouvez utiliser ceci :

; attempt to remove previous versions' icons
[InstallDelete]
Type: filesandordirs; Name: {group}\*;

Cette opération est exécutée "au début de l'installation" et supprime les anciennes icônes. Les nouvelles icônes seront toujours installées une fois l'opération terminée.

Je fais cela à chaque installation "au cas où quelque chose aurait changé" au niveau des icônes (tout est réinstallé de toute façon).

0 votes

Si vous avez des mises à jour pour vos icônes, laissez-les écraser. Il n'y a pas besoin de les supprimer. Eh bien, si vous voulez les supprimer, vous pouvez utiliser cette option. C'est la bonne méthode. Quoi qu'il en soit, le gars à qui vous avez parlé (mlaan, Martijn Laan) est l'auteur de Inno Setup et je pense qu'il sait de quoi il parle :-)

1 votes

Oui, c'est lorsque vous voulez renommer ou déplacer une icône que vous en avez besoin. Par exemple, si la v5 a une icône nommée "run" et que la v6 l'a renommée en "run basic", si un utilisateur installe la v5 puis la v6, il se retrouvera avec 2 icônes, alors que vous n'en vouliez qu'une ("run basic"). Donc cette astuce finit par être nécessaire (@mlaan +1 pour changer le comportement par défaut de innosetup pour qu'il supprime les anciennes icônes et n'ait pas besoin de ça...)

6voto

mlaan Points 257

Lorsque vous utilisez Inno Setup, il n'y a aucune raison de désinstaller une version précédente, sauf si cette version a été installée par un programme d'installation différent. Sinon, les mises à jour sont gérées automatiquement.

7 votes

Notre programme a été modifié dans sa structure, donc l'ancienne version doit être désinstallée.

11 votes

Non, vous pouvez ajouter des entrées à votre script pour gérer le changement de structure pendant une mise à jour.

1 votes

@mlaan Et quelles seraient ces entrées ?

2voto

La réponse fournie par Craig McQueen est tout à fait viable. Cependant, j'ajouterais ces commentaires :

  • Le site {#emit SetupSetting("AppId")} ne fonctionne pas pour moi, donc j'ajoute juste mon App ID.
  • Je ne voulais pas exécuter mon programme de désinstallation, car j'ai un fichier de configuration INI stocké dans le dossier AppData/ qui est supprimé par le désinstalleur, et je ne veux pas qu'il soit effacé lors de l'installation d'une nouvelle version. J'ai donc modifié un peu le code fourni par Craig McQueen pour supprimer le répertoire où est installé le programme, après avoir récupéré son chemin.

Donc, en ce qui concerne le code de Craig McQueen, les changements sont :

  • Récupérer le InstallLocation au lieu de la touche UninstallString clé.
  • Utilisez le DelTree au lieu de la fonction Exec(sUnInstallString, ...)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X