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?
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!
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.
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.
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).
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 fonctionExec(sUnInstallString, ...)
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;
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.
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!
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.
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.
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