-
Notifications
You must be signed in to change notification settings - Fork 91
Expand file tree
/
Copy pathInstaller.iss
More file actions
401 lines (333 loc) · 12.1 KB
/
Installer.iss
File metadata and controls
401 lines (333 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
; Script generated by the Inno Script Studio Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "EDDI"
#define MyAppVersion "5.0.2"
#define MyAppPublisher "Elite Dangerous Community Developers (EDCD)"
#define MyAppURL "https://github.com/EDCD/EDDI/"
#define MyAppExeName "EDDI.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AllowUNCPath=no
AppId={{830C0324-30D8-423C-B5B4-D7EE8D007A79}
AppName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
AppVerName={#MyAppName} {#MyAppVersion}
AppVersion={#MyAppVersion}
CloseApplications=yes
DefaultDirName={code:GetDefaultInstallDir}
DefaultGroupName={#MyAppName}
DirExistsWarning=no
DisableDirPage=no
DisableWelcomePage=no
LicenseFile="{#SourcePath}\LicenseFile.txt"
OutputBaseFilename={#MyAppName}-{#MyAppVersion}
OutputDir="{#SourcePath}\bin\Installer"
RestartApplications=no
SolidCompression=yes
SourceDir="{#SourcePath}\bin\Release"
UninstallDisplayIcon={app}\{#MyAppExeName}
UsePreviousAppDir=no
UsePreviousTasks=no
WizardImageFile={#SourcePath}\graphics\logo.bmp
WizardSmallImageFile={#SourcePath}\graphics\logo.bmp
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
[Files]
Source: "*.exe"; DestDir: "{app}"
Source: "*.exe.config"; DestDir: "{app}"; Flags: skipifsourcedoesntexist
Source: "runtimes\*.*"; DestDir: "{app}\runtimes"; Flags: recursesubdirs createallsubdirs
Source: "*.dll"; DestDir: "{app}"; Excludes: "Tests.dll"
Source: "*.dll.config"; DestDir: "{app}"; Flags: skipifsourcedoesntexist
Source: "*.resources.dll"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs
Source: "eddi.json"; DestDir: "{app}"
Source: "eddi.*.json"; DestDir: "{app}"
Source: "*.md"; DestDir: "{app}"
Source: "*.vap"; DestDir: "{app}"
; Remove outdated files
[InstallDelete]
; --- Remove old architecture folders entirely ---
Type: filesandordirs; Name: "{app}\x86"
Type: filesandordirs; Name: "{app}\x64"
Type: filesandordirs; Name: "{app}\runtimes"
; --- Remove all old DLLs in the root folder ---
Type: files; Name: "{app}\*.dll"
; --- Remove old PDBs ---
Type: files; Name: "{app}\*.pdb"
; --- Remove old doc files ---
Type: files; Name: "{app}\*.md"
Type: files; Name: "{app}\*.xml"
; --- Remove old default personality files ---
Type: files; Name: "{app}\eddi.json"
Type: files; Name: "{app}\eddi.*.json"
; --- Remove old VoiceAttack profiles ---
Type: files; Name: "{app}\*.vap"
; --- Remove old resource files that may no longer be valid ---
Type: filesandordirs; Name: "{app}\*\*.resources.dll"
; --- Remove old config files that may no longer be valid ---
Type: files; Name: "{app}\*.dll.config"
; --- Remove old user-specific cached configs that cause runtime mismatches ---
Type: filesandordirs; Name: "{localappdata}\Eddi\Eddi.exe_*"
Type: files; Name: "{localappdata}\Eddi\Eddi.exe_*\*\user.config"
; --- Remove obsolete legacy files from older EDDI versions ---
Type: files; Name: "{app}\*.exe"
Type: files; Name: "{app}\*.exe.config"
Type: files; Name: "{app}\EDDI.ico"
Type: files; Name: "{userappdata}\EDDI\credentials.json"
Type: files; Name: "{userappdata}\EDDI\elite.json"
Type: filesandordirs; Name: "{userappdata}\EDDI\galnet"
; Remove sensitive data on uninstall
[UninstallDelete]
Type: files; Name: "{userappdata}\EDDI\CompanionAPI.json"
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon
[Run]
; Manual / non-silent installer launch option.
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
; Silent in-app upgrade launch.
; This always launches the newly installed executable.
Filename: "{app}\{#MyAppExeName}"; Flags: nowait skipifnotsilent runasoriginaluser; Check: ShouldRunAfterInAppUpgrade
[Messages]
SelectDirBrowseLabel=To continue, click Next. If this is not your VoiceAttack 2 installation location, or you would like to put the EDDI files in a different location, click Browse.
[Registry]
Root: "HKLM"; Subkey: "Software\Classes\eddi"; ValueType: string; ValueData: "EDDI URL Protocol"; Flags: uninsdeletekey
Root: "HKLM"; Subkey: "Software\Classes\eddi"; ValueType: string; ValueName: "URL Protocol"; Flags: uninsdeletekey
Root: "HKLM"; Subkey: "Software\Classes\eddi\Default Icon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletekey
Root: "HKLM"; Subkey: "Software\Classes\eddi\shell\open\command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey
Root: "HKLM"; Subkey: "Software\Classes\eddi\shell\open\ddeexec"; ValueType: string; ValueData: "%1"; Flags: uninsdeletekey
Root: "HKCU"; Subkey: "Software\Classes\eddi"; ValueType: string; ValueData: "EDDI URL Protocol"; Flags: uninsdeletekey
Root: "HKCU"; Subkey: "Software\Classes\eddi"; ValueType: string; ValueName: "URL Protocol"; Flags: uninsdeletekey
Root: "HKCU"; Subkey: "Software\Classes\eddi\Default Icon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletekey
Root: "HKCU"; Subkey: "Software\Classes\eddi\shell\open\command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey
Root: "HKCU"; Subkey: "Software\Classes\eddi\shell\open\ddeexec"; ValueType: string; ValueData: "%1"; Flags: uninsdeletekey
[Code]
var
LegacySilentMigration: Boolean;
function NormalizePath(const S: string): string;
begin
Result := Lowercase(RemoveBackslashUnlessRoot(S));
end;
function SamePath(const A, B: string): Boolean;
begin
Result := NormalizePath(A) = NormalizePath(B);
end;
function IsUnderPath(const Child, Parent: string): Boolean;
var
C, P: string;
begin
C := NormalizePath(Child);
P := NormalizePath(Parent);
Result := (C = P) or (Pos(P + '\', C) = 1);
end;
function TryGetVoiceAttack2AppsDir(var Dir: string): Boolean;
var
VAFolder: string;
begin
Result := False;
if RegQueryStringValue(
HKCU,
'Software\VoiceAttack.com\VoiceAttack2\LastRun',
'AppsFolder',
Dir) and (Trim(Dir) <> '') then
begin
Dir := RemoveBackslashUnlessRoot(Dir);
Result := True;
exit;
end;
if RegQueryStringValue(
HKCU,
'Software\VoiceAttack.com\VoiceAttack2\LastRun',
'VAFolder',
VAFolder) and (Trim(VAFolder) <> '') then
begin
Dir := AddBackslash(RemoveBackslashUnlessRoot(VAFolder)) + 'Apps';
Result := True;
end;
end;
function GetDefaultInstallDir(Param: string): string;
var
AppsFolder: string;
begin
if TryGetVoiceAttack2AppsDir(AppsFolder) then
begin
Result := AddBackslash(RemoveBackslashUnlessRoot(AppsFolder)) + '{#MyAppName}';
exit;
end;
Result := ExpandConstant('{userappdata}\VoiceAttack2\Apps\{#MyAppName}');
end;
function GetVoiceAttack2EddiDir: string;
var
AppsFolder: string;
begin
if TryGetVoiceAttack2AppsDir(AppsFolder) then
begin
Result := AddBackslash(RemoveBackslashUnlessRoot(AppsFolder)) + '{#MyAppName}';
exit;
end;
Result := ExpandConstant('{userappdata}\VoiceAttack2\Apps\{#MyAppName}');
end;
function GetPreviousEddiInstallDir: string;
begin
Result := '';
RegQueryStringValue(
HKLM,
'Software\Microsoft\Windows\CurrentVersion\Uninstall\{830C0324-30D8-423C-B5B4-D7EE8D007A79}_is1',
'InstallLocation',
Result);
if Trim(Result) <> '' then
Result := RemoveBackslashUnlessRoot(Result);
end;
function TryGetLegacyVoiceAttackAppsDir(var Dir: string): Boolean;
var
VAFolder: string;
begin
Result := False;
if RegQueryStringValue(
HKCU,
'Software\VoiceAttack.com\VoiceAttack\LastRun',
'AppsFolder',
Dir) and (Trim(Dir) <> '') then
begin
Dir := RemoveBackslashUnlessRoot(Dir);
Result := True;
exit;
end;
if RegQueryStringValue(
HKCU,
'Software\VoiceAttack.com\VoiceAttack\LastRun',
'VAFolder',
VAFolder) and (Trim(VAFolder) <> '') then
begin
Dir := AddBackslash(RemoveBackslashUnlessRoot(VAFolder)) + 'Apps';
Result := True;
end;
end;
function GetLegacyEddiDir: string;
var
LegacyAppsDir: string;
begin
Result := '';
if TryGetLegacyVoiceAttackAppsDir(LegacyAppsDir) then
Result := AddBackslash(RemoveBackslashUnlessRoot(LegacyAppsDir)) + '{#MyAppName}';
end;
function IsLegacyVoiceAttackPath(const Dir: string): Boolean;
var
LegacyAppsDir: string;
VoiceAttack2AppsDir: string;
begin
Result := False;
if not TryGetLegacyVoiceAttackAppsDir(LegacyAppsDir) then
exit;
{
VoiceAttack supports an in-place v1 -> v2 upgrade. In that case both
registry hives can legitimately point to the same Apps folder. Do not
block the selected path as legacy when the v1 and v2 Apps folders match.
}
if TryGetVoiceAttack2AppsDir(VoiceAttack2AppsDir) and
SamePath(LegacyAppsDir, VoiceAttack2AppsDir) then
begin
Log(Format(
'VoiceAttack and VoiceAttack 2 are registered to the same Apps folder: "%s".', [LegacyAppsDir]));
exit;
end;
Result := IsUnderPath(Dir, LegacyAppsDir);
end;
function IsInAppUpgrade: Boolean;
begin
Result := ExpandConstant('{param:EDDIInAppUpgrade|0}') = '1';
end;
function ShouldRunAfterInAppUpgrade: Boolean;
begin
Result := IsInAppUpgrade or LegacySilentMigration;
end;
procedure RegisterCloseResource(const Dir: string);
var
ExePath: string;
begin
if Trim(Dir) = '' then
exit;
ExePath := AddBackslash(RemoveBackslashUnlessRoot(Dir)) + '{#MyAppExeName}';
if FileExists(ExePath) then
RegisterExtraCloseApplicationsResource(False, ExePath);
end;
procedure RegisterExtraCloseApplicationsResources;
begin
RegisterCloseResource(GetLegacyEddiDir);
RegisterCloseResource(GetPreviousEddiInstallDir);
end;
function RemoveDirIfOldEddiInstall(const Dir: string): Boolean;
var
CleanDir: string;
begin
Result := True;
if Trim(Dir) = '' then
exit;
CleanDir := RemoveBackslashUnlessRoot(Dir);
if not DirExists(CleanDir) then
exit;
if SamePath(CleanDir, ExpandConstant('{app}')) then
exit;
if FileExists(AddBackslash(CleanDir) + '{#MyAppExeName}') then
begin
Log(Format('Removing old EDDI install at "%s".', [CleanDir]));
Result := DelTree(CleanDir, True, True, True);
end;
end;
function RemoveOldEddiInstalls: Boolean;
begin
Result :=
RemoveDirIfOldEddiInstall(GetLegacyEddiDir) and
RemoveDirIfOldEddiInstall(GetPreviousEddiInstallDir);
end;
function NextButtonClick(CurPageID: Integer): Boolean;
var
ChosenDir: string;
TargetDir: string;
begin
Result := True;
if CurPageID = wpSelectDir then
begin
ChosenDir := RemoveBackslashUnlessRoot(WizardDirValue);
if IsLegacyVoiceAttackPath(ChosenDir) then
begin
if WizardSilent then
begin
TargetDir := GetVoiceAttack2EddiDir;
Log(Format('Silent legacy in-app upgrade path detected. Replacing selected directory "%s" with "%s".', [ChosenDir, TargetDir]));
WizardForm.DirEdit.Text := TargetDir;
LegacySilentMigration := True;
Result := True;
exit;
end;
MsgBox(
'Installing EDDI into the legacy VoiceAttack plugin location is no longer supported.' + #13#10#13#10 +
'Select the new VoiceAttack 2 Apps folder instead.',
mbError, MB_OK);
Result := False;
end;
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if not RemoveOldEddiInstalls then
begin
MsgBox(
'Setup could not remove an old EDDI install.' + #13#10#13#10 +
'Close EDDI and VoiceAttack, then run Setup again.',
mbCriticalError, MB_OK);
Abort;
end;
end;
end;