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

J'utilise Inno Setup pour créer un installateur.

je veux que l'installateur désinstalle automatiquement la version installée précédente, au lieu de l'écraser. Comment puis-je le faire?

77
demandé sur Martin Prikryl 2010-01-04 18:44:35

11 réponses

vous devriez être en mesure de lire la chaîne de désinstallation du Registre, Compte tenu de L'AppId (c'est-à-dire la valeur que vous avez utilisée pour AppID dans la section [Setup] ). Il peut être trouvé sous Software\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\ (peut être HKLM ou HKCU , donc mieux cochez les deux) où {AppId} doit être substitué avec la valeur réelle que vous avez utilisé. Recherchez les valeurs UninstallString ou QuietUninstallString et utilisez la fonction Exec pour l'exécuter à partir de votre fonction InitializeSetup() .

mise à Jour: retiré de non-travail solution de rechange à l'aide d'un [Run] -la section d'entrée avec {uninstallexe} - merci à tous les commentateurs qui ont fait cela!

25
répondu Oliver Giesen 2011-04-11 12:59:24

j'ai utilisé ce qui suit. Je ne suis pas sûr que ce soit la façon la plus simple de le faire, mais ça marche.

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

/////////////////////////////////////////////////////////////////////
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 blog "Inno Setup Exemple de Script pour la Version" de Comparaison qui va plus loin, et lit le numéro de version de n'importe quelle version précédemment installée, et compare ce numéro de version avec celui du paquet d'installation actuel.

92
répondu Craig McQueen 2017-05-11 04:58:11

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

7
répondu mlaan 2010-03-25 10:29:22

si vous "voulez simplement supprimer les anciennes icônes" (parce que les vôtres ont changé/mis à jour) vous pouvez utiliser ceci:

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

C'est au début de l'installation" donc, fondamentalement, supprime les anciennes icônes, et de nouveaux seront toujours installés là après c'est complètement terminé.

je le fais avec chaque installation "dans le cas où quelque chose a changé" icône sage (tout est réinstallé de toute façon).

6
répondu rogerdpack 2015-08-06 21:25:24

La réponse fournie par Craig McQueen est totalement viable. Bien que, je voudrais ajouter ces commentaires:

  • le code {#emit SetupSetting("AppId")} ne fonctionne pas pour moi, donc je viens d'ajouter mon application.
  • Je ne voulais pas exécuter mon programme de désinstallation, parce que j'ai un fichier de configuration INI stocké dans le dossier AppData/ qui est supprimé par le désinstallateur, et je ne veux pas qu'il soit effacé lors de l'installation d'une nouvelle version. Donc, j'ai 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érez la clé InstallLocation au lieu de la clé UninstallString .
  • utilisez la fonction DelTree au lieu de la fonction Exec(sUnInstallString, ...)
2
répondu 2011-03-08 16:56:45

j'ai été édité @Crain Mc-Queen code , je pense que ce code est mieux parce que pas besoin de modifier dans un autre projet :

[Code]
function GetNumber(var temp: String): Integer;
var
  part: String;
  pos1: Integer;
begin
  if Length(temp) = 0 then
  begin
    Result := -1;
    Exit;
  end;
    pos1 := Pos('.', temp);
    if (pos1 = 0) then
    begin
      Result := StrToInt(temp);
    temp := '';
    end
    else
    begin
    part := Copy(temp, 1, pos1 - 1);
      temp := Copy(temp, pos1 + 1, Length(temp));
      Result := StrToInt(part);
    end;
end;

function CompareInner(var temp1, temp2: String): Integer;
var
  num1, num2: Integer;
begin
    num1 := GetNumber(temp1);
  num2 := GetNumber(temp2);
  if (num1 = -1) or (num2 = -1) then
  begin
    Result := 0;
    Exit;
  end;
      if (num1 > num2) then
      begin
        Result := 1;
      end
      else if (num1 < num2) then
      begin
        Result := -1;
      end
      else
      begin
        Result := CompareInner(temp1, temp2);
      end;
end;

function CompareVersion(str1, str2: String): Integer;
var
  temp1, temp2: String;
begin
    temp1 := str1;
    temp2 := str2;
    Result := CompareInner(temp1, temp2);
end;

function InitializeSetup(): Boolean;
var
  oldVersion: String;
  uninstaller: String;
  ErrorCode: Integer;
  vCurID      :String;
  vCurAppName :String;
begin
  vCurID:= '{#SetupSetting("AppId")}';
  vCurAppName:= '{#SetupSetting("AppName")}';
  //remove first "{" of ID
  vCurID:= Copy(vCurID, 2, Length(vCurID) - 1);
  //
  if RegKeyExists(HKEY_LOCAL_MACHINE,
    'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1') then
  begin
    RegQueryStringValue(HKEY_LOCAL_MACHINE,
      'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1',
      'DisplayVersion', oldVersion);
    if (CompareVersion(oldVersion, '{#SetupSetting("AppVersion")}') < 0) then      
    begin
      if MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. Continue to use this old version?',
        mbConfirmation, MB_YESNO) = IDYES then
      begin
        Result := False;
      end
      else
      begin
          RegQueryStringValue(HKEY_LOCAL_MACHINE,
            'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1',
            'UninstallString', uninstaller);
          ShellExec('runas', uninstaller, '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
          Result := True;
      end;
    end
    else
    begin
      MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. This installer will exit.',
        mbInformation, MB_OK);
      Result := False;
    end;
  end
  else
  begin
    Result := True;
  end;
end;
1
répondu MohsenB 2013-11-29 15:10:16

vous pouvez exec an uninstaller dans la section [code]. Vous devez trouver comment obtenir le chemin vers le désinstallateur existant. Pour la simplicité quand j'installe mes applications j'ajoute une valeur de chaîne de Registre qui pointe vers le dossier contenant le désinstallant, et juste exec le désinstallant dans le rappel InitializeWizard.

Gardez à l'esprit que Inno setup programme de désinstallation noms sont tous de la forme uninsnnn.exe, tu dois en tenir compte dans ton code.

0
répondu Jim In Texas 2011-01-05 00:04:49

pour toute personne qui utilise le GetUninstallString() suggéré ci-dessus pour forcer une désinstallation à l'intérieur de CurStepChanged() et a des problèmes de cache de disque, voir ci-dessous pour une solution associée qui attend réellement un moment après unistallation pour le exe désinstaller à supprimer!

problème de cache de disque avec inno-setup?

0
répondu fubar 2017-05-23 12:10:10

je dois rater quelque chose. Les fichiers new sont copiés dans le répertoire cible avant la suppression de l'ancienne installation. puis vient le désinstallateur les supprime et supprime le répertoire.

-1
répondu Shaul 2014-04-02 06:16:05

N'utilisez pas la section [exécuter], mais la section [Désinstaller]. Infact, le programme sous [Run] sont exécutés après l'installation, provoquant la désinstallation de votre programme immédiatement après l'installation :-| À la place, la section [UninstallRun] est évaluée avant l'installation.

-8
répondu Andrea Ferroni alias bubbakk 2010-11-23 12:41:27

suivez ce lien: http://news.jrsoftware.org/news/innosetup/msg55323.html

dans la fonction InitializeSetup (), vous pouvez appeler "MSIEXEC /x {votre ID de programme}" après l'invite de l'utilisateur à désinstaller l'ancienne version

-8
répondu Tonny Nguyen 2011-01-06 03:33:45