Skip to content

Commit 8f3c2a6

Browse files
brsonalexcrichton
authored andcommitted
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.
1 parent a5dcbc6 commit 8f3c2a6

File tree

4 files changed

+75
-3
lines changed

4 files changed

+75
-3
lines changed

mk/dist.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ PKG_EXE = dist/$(PKG_NAME)-install.exe
118118
%.ico: $(S)src/etc/pkg/%.ico
119119
cp $< $@
120120

121-
$(PKG_EXE): rust.iss modpath.iss LICENSE.txt rust-logo.ico \
121+
$(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \
122122
$(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \
123123
dist-prepare-win
124124
$(CFG_PYTHON) $(S)src/etc/copy-runtime-deps.py tmp/dist/win/bin

src/etc/pkg/modpath.iss

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ begin
164164
end;
165165
166166
167-
procedure CurStepChanged(CurStep: TSetupStep);
167+
procedure ModPathCurStepChanged(CurStep: TSetupStep);
168168
var
169169
taskname: String;
170170
begin

src/etc/pkg/rust.iss

+12-1
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,15 @@ begin
4949
setArrayLength(Result, 1)
5050
Result[0] := ExpandConstant('{app}\bin');
5151
end;
52-
#include "modpath.iss"
52+
53+
#include "modpath.iss"
54+
#include "upgrade.iss"
55+
56+
// Both modpath.iss and upgrade.iss want to overload CurStepChanged.
57+
// This version does the overload then delegates to each.
58+
59+
procedure CurStepChanged(CurStep: TSetupStep);
60+
begin
61+
UpgradeCurStepChanged(CurStep);
62+
ModPathCurStepChanged(CurStep);
63+
end;

src/etc/pkg/upgrade.iss

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// The following code taken from https://stackoverflow.com/questions/2000296/innosetup-how-to-automatically-uninstall-previous-installed-version
2+
// It performs upgrades by running the uninstaller before the install
3+
4+
/////////////////////////////////////////////////////////////////////
5+
function GetUninstallString(): String;
6+
var
7+
sUnInstPath: String;
8+
sUnInstallString: String;
9+
begin
10+
sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\Rust_is1');
11+
sUnInstallString := '';
12+
if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
13+
RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
14+
Result := sUnInstallString;
15+
end;
16+
17+
18+
/////////////////////////////////////////////////////////////////////
19+
function IsUpgrade(): Boolean;
20+
begin
21+
Result := (GetUninstallString() <> '');
22+
end;
23+
24+
25+
/////////////////////////////////////////////////////////////////////
26+
function UnInstallOldVersion(): Integer;
27+
var
28+
sUnInstallString: String;
29+
iResultCode: Integer;
30+
begin
31+
// Return Values:
32+
// 1 - uninstall string is empty
33+
// 2 - error executing the UnInstallString
34+
// 3 - successfully executed the UnInstallString
35+
36+
// default return value
37+
Result := 0;
38+
39+
// get the uninstall string of the old app
40+
sUnInstallString := GetUninstallString();
41+
if sUnInstallString <> '' then begin
42+
sUnInstallString := RemoveQuotes(sUnInstallString);
43+
if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
44+
Result := 3
45+
else
46+
Result := 2;
47+
end else
48+
Result := 1;
49+
end;
50+
51+
/////////////////////////////////////////////////////////////////////
52+
procedure UpgradeCurStepChanged(CurStep: TSetupStep);
53+
begin
54+
if (CurStep=ssInstall) then
55+
begin
56+
if (IsUpgrade()) then
57+
begin
58+
UnInstallOldVersion();
59+
end;
60+
end;
61+
end;

0 commit comments

Comments
 (0)