From 8f3c2a6ffdd578eb0213c365fa75e9622167d63e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 11 Apr 2014 18:20:10 -0700 Subject: [PATCH] dist: Make Windows installer uninstall first. Closes #9563 This will remove existing files before installing new ones. Note that I took some code with no license from stackoverflow, as indicated in comments. --- mk/dist.mk | 2 +- src/etc/pkg/modpath.iss | 2 +- src/etc/pkg/rust.iss | 13 ++++++++- src/etc/pkg/upgrade.iss | 61 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/etc/pkg/upgrade.iss diff --git a/mk/dist.mk b/mk/dist.mk index b96d5bee3af..b14c6f279ef 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -118,7 +118,7 @@ PKG_EXE = dist/$(PKG_NAME)-install.exe %.ico: $(S)src/etc/pkg/%.ico cp $< $@ -$(PKG_EXE): rust.iss modpath.iss LICENSE.txt rust-logo.ico \ +$(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \ $(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \ dist-prepare-win $(CFG_PYTHON) $(S)src/etc/copy-runtime-deps.py tmp/dist/win/bin diff --git a/src/etc/pkg/modpath.iss b/src/etc/pkg/modpath.iss index c0b4475ad05..35cc0097035 100644 --- a/src/etc/pkg/modpath.iss +++ b/src/etc/pkg/modpath.iss @@ -164,7 +164,7 @@ begin end; -procedure CurStepChanged(CurStep: TSetupStep); +procedure ModPathCurStepChanged(CurStep: TSetupStep); var taskname: String; begin diff --git a/src/etc/pkg/rust.iss b/src/etc/pkg/rust.iss index 66bb71527fe..053fe34952c 100644 --- a/src/etc/pkg/rust.iss +++ b/src/etc/pkg/rust.iss @@ -49,4 +49,15 @@ begin setArrayLength(Result, 1) Result[0] := ExpandConstant('{app}\bin'); end; -#include "modpath.iss" \ No newline at end of file + +#include "modpath.iss" +#include "upgrade.iss" + +// Both modpath.iss and upgrade.iss want to overload CurStepChanged. +// This version does the overload then delegates to each. + +procedure CurStepChanged(CurStep: TSetupStep); +begin + UpgradeCurStepChanged(CurStep); + ModPathCurStepChanged(CurStep); +end; diff --git a/src/etc/pkg/upgrade.iss b/src/etc/pkg/upgrade.iss new file mode 100644 index 00000000000..1d36be57649 --- /dev/null +++ b/src/etc/pkg/upgrade.iss @@ -0,0 +1,61 @@ +// The following code taken from https://stackoverflow.com/questions/2000296/innosetup-how-to-automatically-uninstall-previous-installed-version +// It performs upgrades by running the uninstaller before the install + +///////////////////////////////////////////////////////////////////// +function GetUninstallString(): String; +var + sUnInstPath: String; + sUnInstallString: String; +begin + sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\Rust_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 UpgradeCurStepChanged(CurStep: TSetupStep); +begin + if (CurStep=ssInstall) then + begin + if (IsUpgrade()) then + begin + UnInstallOldVersion(); + end; + end; +end; \ No newline at end of file