1#define APPNAM "HexChat"
2#define APPVER "<#= [string]::Join('.', $versionParts) #>"
3; These are defined by our installer project at build time
4;#define APPARCH "x64"
5;#define PROJECTDIR "C:\...\hexchat\win32\installer\"
6
7;http://mitrich.net23.net/?/inno-download-plugin.html
8#include <idp.iss>
9
10[Setup]
11AppName=HexChat
12AppVersion={#APPVER}
13AppVerName=HexChat {#APPVER}
14AppPublisher=HexChat
15AppPublisherURL=http://hexchat.github.io
16AppCopyright=Copyright (C) 1998-2010 Peter Zelezny
17AppSupportURL=https://github.com/hexchat/hexchat/issues
18AppUpdatesURL=http://hexchat.github.io/downloads.html
19LicenseFile=share\doc\hexchat\COPYING
20UninstallDisplayIcon={app}\hexchat.exe
21UninstallDisplayName=HexChat
22#if APPARCH == "x64"
23DefaultDirName={pf64}\HexChat
24#else
25DefaultDirName={pf32}\HexChat
26#endif
27DefaultGroupName=HexChat
28DisableProgramGroupPage=yes
29SolidCompression=yes
30Compression=lzma2/ultra64
31SourceDir=..\rel
32OutputDir=..
33#if APPARCH == "x64"
34OutputBaseFilename={#APPNAM}-{#APPVER}_x64
35#else
36OutputBaseFilename={#APPNAM}-{#APPVER}_x86
37#endif
38FlatComponentsList=no
39PrivilegesRequired=none
40ShowComponentSizes=no
41CreateUninstallRegKey=not IsTaskSelected('portable')
42Uninstallable=not IsTaskSelected('portable')
43#if APPARCH == "x64"
44ArchitecturesAllowed=x64
45ArchitecturesInstallIn64BitMode=x64
46#else
47ArchitecturesAllowed=x86 x64
48#endif
49MinVersion=6.1
50WizardImageFile={#PROJECTDIR}wizardimage.bmp
51WizardSmallImageFile={#PROJECTDIR}wizardsmallimage.bmp
52SetupIconFile={#PROJECTDIR}..\..\data\icons\hexchat.ico
53
54[Types]
55Name: "normal"; Description: "Normal Installation"
56Name: "minimal"; Description: "Minimal Installation"
57Name: "custom"; Description: "Custom Installation"; Flags: iscustom
58
59[Components]
60Name: "libs"; Description: "HexChat"; Types: normal minimal custom; Flags: fixed
61Name: "xctext"; Description: "HexChat-Text"; Types: custom; Flags: disablenouninstallwarning
62Name: "xtm"; Description: "HexChat Theme Manager"; Types: normal custom; Flags: disablenouninstallwarning
63Name: "translations"; Description: "Translations"; Types: normal custom; Flags: disablenouninstallwarning
64Name: "spell"; Description: "Spelling Dictionaries"; Types: custom; Flags: disablenouninstallwarning
65Name: "plugins"; Description: "Plugins"; Types: custom; Flags: disablenouninstallwarning
66Name: "plugins\checksum"; Description: "Checksum"; Types: custom; Flags: disablenouninstallwarning
67Name: "plugins\exec"; Description: "Exec"; Types: custom; Flags: disablenouninstallwarning
68Name: "plugins\fishlim"; Description: "FiSHLiM"; Types: custom; Flags: disablenouninstallwarning
69Name: "plugins\sysinfo"; Description: "SysInfo"; Types: custom; Flags: disablenouninstallwarning
70Name: "plugins\upd"; Description: "Update Checker"; Types: normal custom; Flags: disablenouninstallwarning
71Name: "plugins\winamp"; Description: "Winamp"; Types: custom; Flags: disablenouninstallwarning
72Name: "langs"; Description: "Language Interfaces"; Types: custom; Flags: disablenouninstallwarning
73Name: "langs\lua"; Description: "Lua"; Types: normal custom; Flags: disablenouninstallwarning
74Name: "langs\perl"; Description: "Perl (requires Perl 5.20)"; Types: custom; Flags: disablenouninstallwarning
75Name: "langs\python"; Description: "Python Interface"; Types: custom; Flags: disablenouninstallwarning
76Name: "langs\python\python2"; Description: "Python (requires Python 2.7)"; Types: custom; Flags: disablenouninstallwarning exclusive
77Name: "langs\python\python3"; Description: "Python (requires Python 3.6)"; Types: custom; Flags: disablenouninstallwarning exclusive
78
79[Tasks]
80Name: portable; Description: "Yes"; GroupDescription: "Portable Mode: Stores configuration files within install directory for portable drives."; Flags: unchecked
81
82[Registry]
83Root: HKCR; Subkey: "irc"; ValueType: none; ValueName: ""; ValueData: ""; Flags: deletekey uninsdeletekey; Tasks: not portable
84Root: HKCR; Subkey: "irc"; ValueType: string; ValueName: ""; ValueData: "URL:IRC Protocol"; Flags: uninsdeletevalue; Tasks: not portable
85Root: HKCR; Subkey: "irc"; ValueType: string; ValueName: "URL Protocol"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
86Root: HKCR; Subkey: "irc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\hexchat.exe,0"; Flags: uninsdeletevalue; Tasks: not portable
87Root: HKCR; Subkey: "irc\shell"; ValueType: string; ValueName: ""; ValueData: "open"; Flags: uninsdeletevalue; Tasks: not portable
88Root: HKCR; Subkey: "irc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\hexchat.exe --url=""%1"""; Flags: uninsdeletevalue; Tasks: not portable
89
90Root: HKCR; Subkey: ".hct"; ValueType: none; ValueName: ""; ValueData: ""; Flags: deletekey uninsdeletekey; Components:xtm; Tasks: not portable
91Root: HKCR; Subkey: ".hct"; ValueType: string; ValueName: ""; ValueData: "HexChat Theme File"; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable
92Root: HKCR; Subkey: ".hct"; ValueType: string; ValueName: "HexChat Theme File"; ValueData: ""; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable
93Root: HKCR; Subkey: ".hct\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\thememan.exe,0"; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable
94Root: HKCR; Subkey: ".hct\shell"; ValueType: string; ValueName: ""; ValueData: "open"; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable
95Root: HKCR; Subkey: ".hct\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\thememan.exe ""%1"""; Flags: uninsdeletevalue; Components:xtm; Tasks: not portable
96
97[Run]
98Filename: "{app}\hexchat.exe"; Description: "Run HexChat after closing the Wizard"; Flags: nowait postinstall skipifsilent
99Filename: "http://docs.hexchat.org/en/latest/changelog.html"; Description: "See what's changed"; Flags: shellexec runasoriginaluser postinstall skipifsilent unchecked
100Filename: "{tmp}\vcredist.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "Installing Visual C++ Redistributable"; Flags: skipifdoesntexist; Tasks: not portable
101Filename: "{tmp}\vcredist2013.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "Installing Visual C++ Redistributable"; Flags: skipifdoesntexist; Tasks: not portable
102Filename: "{tmp}\dotnet4.exe"; Parameters: "/q /norestart"; StatusMsg: "Installing .NET"; Components: xtm; Flags: skipifdoesntexist; Tasks: not portable
103Filename: "{tmp}\perl.msi"; StatusMsg: "Installing Perl"; Components: langs\perl; Flags: shellexec skipifdoesntexist; Tasks: not portable
104Filename: "{tmp}\python.msi"; StatusMsg: "Installing Python"; Components: langs\python; Flags: shellexec skipifdoesntexist; Tasks: not portable
105Filename: "{tmp}\python.exe"; Parameters: "InstallAllUsers=1 PrependPath=1"; StatusMsg: "Installing Python"; Components: langs\python; Flags: shellexec skipifdoesntexist; Tasks: not portable
106Filename: "{tmp}\spelling-dicts.exe"; Parameters: "/verysilent"; StatusMsg: "Installing Spelling Dictionaries"; Components: spell; Flags: skipifdoesntexist; Tasks: not portable
107
108[Files]
109Source: "portable-mode"; DestDir: "{app}"; Tasks: portable
110
111Source: "changelog.url"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
112Source: "readme.url"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
113Source: "cert.pem"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
114Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
115Source: "share\doc\*"; DestDir: "{app}\share\doc"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
116Source: "share\themes\MS-Windows\*"; DestDir: "{app}\share\themes\MS-Windows"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
117Source: "share\locale\*"; DestDir: "{app}\share\locale"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: translations
118Source: "etc\fonts\*"; DestDir: "{app}\etc\fonts"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
119
120Source: "atk-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
121Source: "cairo.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
122Source: "freetype.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
123Source: "fribidi-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
124Source: "fontconfig.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
125Source: "gdk_pixbuf-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
126Source: "gdk-win32-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
127Source: "gio-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
128Source: "glib-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
129Source: "gmodule-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
130Source: "gobject-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
131#if APPARCH == "x64"
132Source: "gspawn-win64-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
133Source: "gspawn-win64-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
134#else
135Source: "gspawn-win32-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
136Source: "gspawn-win32-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
137#endif
138Source: "gthread-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
139Source: "gtk-win32-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
140Source: "iconv.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
141#if APPARCH == "x64"
142Source: "libcrypto-1_1-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
143Source: "libssl-1_1-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
144#else
145Source: "libcrypto-1_1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
146Source: "libssl-1_1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
147#endif
148Source: "libenchant.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
149Source: "ffi-7.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
150Source: "intl.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
151Source: "libpng16.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
152Source: "libxml2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
153Source: "pango-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
154Source: "pangocairo-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
155Source: "pangoft2-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
156Source: "pangowin32-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
157Source: "zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
158
159Source: "plugins\hcnotifications-winrt.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: libs
160
161Source: "lib\enchant\*"; DestDir: "{app}\lib\enchant"; Flags: ignoreversion; Components: libs
162
163Source: "lib\gtk-2.0\i686-pc-vs14\engines\*"; DestDir: "{app}\lib\gtk-2.0\i686-pc-vs14\engines"; Flags: ignoreversion; Components: libs
164
165Source: "girepository-1.0-1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua
166Source: "lua51.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua
167Source: "lib\lua\lgi\*.dll"; DestDir: "{app}\lib\lua\lgi"; Flags: ignoreversion; Components: langs\lua
168Source: "lib\girepository-1.0\*.typelib"; DestDir: "{app}\lib\girepository-1.0"; Flags: ignoreversion; Components: langs\lua
169Source: "share\lua\*.lua"; DestDir: "{app}\share\lua"; Flags: ignoreversion; Components: langs\lua
170Source: "share\lua\lgi\*.lua"; DestDir: "{app}\share\lua\lgi"; Flags: ignoreversion; Components: langs\lua
171Source: "share\lua\lgi\override\*.lua"; DestDir: "{app}\share\lua\lgi\override"; Flags: ignoreversion; Components: langs\lua
172Source: "plugins\hclua.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\lua
173
174Source: "plugins\hcchecksum.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\checksum
175Source: "plugins\hcexec.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\exec
176Source: "plugins\hcfishlim.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\fishlim
177Source: "share\music.png"; DestDir: "{app}\share"; Flags: ignoreversion; Components: plugins\winamp
178Source: "share\download.png"; DestDir: "{app}\share"; Flags: ignoreversion; Components: plugins\upd
179Source: "plugins\hcupd.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\upd
180Source: "WinSparkle.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: plugins\upd
181Source: "plugins\hcwinamp.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\winamp
182Source: "share\system.png"; DestDir: "{app}\share"; Flags: ignoreversion; Components: plugins\sysinfo
183Source: "plugins\hcsysinfo.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\sysinfo
184Source: "plugins\hcperl.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\perl
185
186Source: "python\*.py"; DestDir: "{app}\python"; Flags: ignoreversion; Components: langs\python
187
188Source: "plugins\hcpython2.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python\python2
189Source: "_cffi_backend.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python\python2
190
191Source: "plugins\hcpython3.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python\python3
192Source: "_cffi_backend.cp3*.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python\python3
193
194Source: "hexchat.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
195Source: "hexchat-text.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xctext
196Source: "thememan.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xtm
197
198[Icons]
199Name: "{group}\HexChat"; Filename: "{app}\hexchat.exe"; AppUserModelID: "HexChat.Desktop.Notify"; Tasks: not portable
200Name: "{group}\HexChat Safe Mode"; Filename: "{app}\hexchat.exe"; Parameters: "--no-auto --no-plugins"; Tasks: not portable
201Name: "{group}\HexChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; Tasks: not portable
202Name: "{group}\HexChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; Tasks: not portable
203Name: "{group}\HexChat Config Folder"; Filename: "%APPDATA%\HexChat\"; Tasks: not portable
204Name: "{group}\HexChat-Text"; Filename: "{app}\hexchat-text.exe"; Components: xctext; Tasks: not portable
205Name: "{group}\HexChat Theme Manager"; Filename: "{app}\thememan.exe"; Components: xtm; Tasks: not portable
206Name: "{group}\Uninstall HexChat"; Filename: "{uninstallexe}"; Tasks: not portable
207
208[Messages]
209BeveledLabel= {#APPNAM}
210
211[Code]
212/////////////////////////////////////////////////////////////////////
213procedure InitializeWizard;
214begin
215	WizardForm.LicenseAcceptedRadio.Checked := True;
216
217	idpDownloadAfter(wpReady);
218end;
219
220/////////////////////////////////////////////////////////////////////
221function GetSysDir(): String;
222begin
223#if APPARCH != "x64"
224	if IsWin64 then
225		Result := ExpandConstant('{syswow64}\')
226	else
227		Result := ExpandConstant('{sys}\');
228#else
229	Result := ExpandConstant('{sys}\');
230#endif
231end;
232
233/////////////////////////////////////////////////////////////////////
234function CheckDLL(DLLName: String): Boolean;
235var
236	ResultCode: Integer;
237begin
238	if ExecAsOriginalUser(GetSysDir() + 'where.exe', '/Q ' + DLLName,
239						'', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
240		Result := ResultCode = 0 // 0 is success
241	else
242		Result := False;
243end;
244
245/////////////////////////////////////////////////////////////////////
246function CheckVCInstall(): Boolean;
247begin
248	Result := FileExists(GetSysDir() + 'vcruntime140.dll');;
249end;
250
251function CheckVC2013Install(): Boolean;
252begin
253	Result := FileExists(GetSysDir() + 'msvcr120.dll');;
254end;
255
256
257/////////////////////////////////////////////////////////////////////
258function CheckSpellInstall(): Boolean;
259var
260	Version: TWindowsVersion;
261begin
262	GetWindowsVersionEx(Version);
263
264	// Windows 8 or greater has built in spell check.
265	if Version.NTPlatform and (Version.Major > 6) or ((Version.Major = 6) and (Version.Minor > 1)) then
266		Result := True
267	else
268		Result := DirExists(ExpandConstant('{localappdata}') + '\enchant\myspell');
269end;
270
271/////////////////////////////////////////////////////////////////////
272function CheckDotNetInstall(): Boolean;
273begin
274	Result := RegKeyExists(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4');
275end;
276
277/////////////////////////////////////////////////////////////////////
278// Sets up the automatic downloads
279/////////////////////////////////////////////////////////////////////
280procedure CurPageChanged(CurPageID: Integer);
281var
282	REDIST: String;
283	REDIST_2013: String;
284	PERL: String;
285	PY2: String;
286	PY3: String;
287	DOTNET: String;
288	SPELL: String;
289begin
290  if(CurPageID = wpReady) then
291  begin
292    idpClearFiles;
293
294	if not IsTaskSelected('portable') then
295	begin
296
297#if APPARCH == "x64"
298		REDIST := 'https://dl.hexchat.net/misc/vcredist_2015_x64.exe';
299		REDIST_2013 := 'https://dl.hexchat.net/misc/vcredist_2013_x64.exe';
300		PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x64.msi';
301		PY2 := 'https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi';
302		PY3 := 'https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64.exe';
303#else
304		REDIST := 'https://dl.hexchat.net/misc/vcredist_2015_x86.exe';
305		REDIST_2013 := 'https://dl.hexchat.net/misc/vcredist_2013_x86.exe';
306		PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x86.msi';
307		PY2 := 'https://www.python.org/ftp/python/2.7.14/python-2.7.14.msi';
308		PY3 := 'https://www.python.org/ftp/python/3.6.4/python-3.6.4.exe';
309#endif
310		DOTNET := 'https://dl.hexchat.net/misc/dotnet_40.exe';
311		SPELL := 'https://dl.hexchat.net/hexchat/HexChat%20Spelling%20Dictionaries%20r2.exe';
312
313		if not CheckVCInstall() then
314			idpAddFile(REDIST, ExpandConstant('{tmp}\vcredist.exe'));
315
316		if IsComponentSelected('xtm') and not CheckDotNetInstall() then
317			idpAddFile(DOTNET, ExpandConstant('{tmp}\dotnet4.exe'));
318
319		if IsComponentSelected('spell') and not CheckSpellInstall() then
320			idpAddFile(SPELL, ExpandConstant('{tmp}\spelling-dicts.exe'));
321
322		if not WizardSilent() then
323		begin
324			if IsComponentSelected('langs\perl') and not CheckDLL('perl520.dll') then
325			begin
326				if not CheckVC2013Install() then
327					idpAddFile(REDIST_2013, ExpandConstant('{tmp}\vcredist2013.exe'));
328
329				idpAddFile(PERL, ExpandConstant('{tmp}\perl.msi'))
330			end;
331
332			if IsComponentSelected('langs\python\python2') and not CheckDLL('python27.dll') then
333				idpAddFile(PY2, ExpandConstant('{tmp}\python.msi'));
334
335			if IsComponentSelected('langs\python\python3') and not CheckDLL('python36.dll') then
336				idpAddFile(PY3, ExpandConstant('{tmp}\python.exe'));
337		end;
338	end;
339  end;
340end;
341
342/////////////////////////////////////////////////////////////////////
343// Disable portable-mode if installing to program files
344/////////////////////////////////////////////////////////////////////
345function NextButtonClick(CurPageID: Integer): Boolean;
346begin
347	if (CurPageID = wpSelectTasks) then
348		if (WizardForm.TasksList.Checked[1] = True) then
349#if APPARCH == "x64"
350			if (WizardDirValue() = ExpandConstant('{pf64}\HexChat')) then
351#else
352			if (WizardDirValue() = ExpandConstant('{pf32}\HexChat')) then
353#endif
354			begin
355				WizardForm.TasksList.Checked[1] := False
356				MsgBox('Portable mode is only intended for use on portable drives and has been disabled.', mbInformation, MB_OK)
357			end;
358
359	Result := True; // Always continue
360end;
361
362/////////////////////////////////////////////////////////////////////
363// these are required for x86->x64 or reverse upgrades
364/////////////////////////////////////////////////////////////////////
365function GetUninstallString(): String;
366var
367	sUnInstPath: String;
368	sUnInstallString: String;
369begin
370#if APPARCH == "x64"
371	sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\HexChat (x64)_is1');
372#else
373	sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\HexChat (x86)_is1');
374#endif
375	sUnInstallString := '';
376	if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
377		RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
378	if not (sUnInstallString <> '') then
379		sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\HexChat_is1');
380				if not RegQueryStringValue(HKLM32, sUnInstPath, 'UninstallString', sUnInstallString) then
381					if not RegQueryStringValue(HKCU32, sUnInstPath, 'UninstallString', sUnInstallString) then
382						if IsWin64 then
383							if not RegQueryStringValue(HKLM64, sUnInstPath, 'UninstallString', sUnInstallString) then
384								RegQueryStringValue(HKCU64, sUnInstPath, 'UninstallString', sUnInstallString);
385	Result := sUnInstallString;
386end;
387
388/////////////////////////////////////////////////////////////////////
389function IsUpgrade(): Boolean;
390begin
391	Result := (GetUninstallString() <> '');
392end;
393
394
395/////////////////////////////////////////////////////////////////////
396function UnInstallOldVersion(): Integer;
397var
398	sUnInstallString: String;
399	iResultCode: Integer;
400begin
401// Return Values:
402// 1 - uninstall string is empty
403// 2 - error executing the UnInstallString
404// 3 - successfully executed the UnInstallString
405
406	// default return value
407	Result := 0;
408
409	// get the uninstall string of the old app
410	sUnInstallString := GetUninstallString();
411	if sUnInstallString <> '' then begin
412		sUnInstallString := RemoveQuotes(sUnInstallString);
413		if Exec(sUnInstallString, '/VERYSILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
414			Result := 3
415		else
416			Result := 2;
417	end else
418		Result := 1;
419end;
420
421/////////////////////////////////////////////////////////////////////
422procedure CurStepChanged(CurStep: TSetupStep);
423begin
424	if not (IsTaskSelected('portable')) then
425	begin
426		if (CurStep=ssInstall) then
427		begin
428			if (IsUpgrade()) then
429			begin
430				UnInstallOldVersion();
431			end;
432			DeleteFile(ExpandConstant('{app}\portable-mode'));
433		end;
434	end;
435end;
436