-
Notifications
You must be signed in to change notification settings - Fork 0
/
leiningen-installer.iss
515 lines (463 loc) · 15.4 KB
/
leiningen-installer.iss
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
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
; InnoSetup 5.5.4 Installer definition for Leiningen - (c) David Powell 2013
#define MyAppName "Leiningen"
#define MyAppVersion "1.0"
#define MyAppPublisher "David Powell"
#define MyAppURL "http://leiningen-win-installer.djpowell.net/"
#define MyInstallerBaseName "leiningen-installer"
[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.)
AppId={{450F3BB7-7198-4401-A147-BDA0BECF6A3A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
#ifndef configure
AppModifyPath="{app}\bin\configure-{#MyInstallerBaseName}.exe"
UninstallFilesDir={app}\bin
OutputBaseFilename={#MyInstallerBaseName}-{#MyAppVersion}
; add some extra space for the bat and jar files
ExtraDiskSpaceRequired=15000000
#endif
#ifdef configure
DisableDirPage=yes
OutputBaseFilename=configure-{#MyInstallerBaseName}
Uninstallable=no
UpdateUninstallLogAppName=no
#endif
DefaultDirName={%LEIN_HOME|{%USERPROFILE}\.lein}
DirExistsWarning=no
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
Compression=zip
SolidCompression=yes
ChangesEnvironment=yes
PrivilegesRequired=lowest
SetupLogging=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Messages]
#ifdef configure
WelcomeLabel2=This will configure [name] on your computer.%n%nIt is recommended that you close all other applications before continuing.
WizardReady=Ready to Configure
ReadyLabel1=Setup is now ready to begin configuring [name] on your computer.
ReadyLabel2a=Click Configure to continue, or click Back if you want to review or change any settings.
ReadyLabel2b=Click Configure to continue with the installation.
ButtonInstall=&Configure
WizardInstalling=Configuring
InstallingLabel=Please wait while Setup configures [name] on your computer.
FinishedLabelNoIcons=Setup has finished configuring [name] on your computer.
#endif
[Files]
#ifndef configure
Source: "curl.exe"; DestDir: "{app}\bin"
Source: "curl-ca-bundle.crt"; DestDir: "{app}\bin"
Source: "license.txt"; DestDir: "{app}\bin"
Source: "file-assoc-in-0.1.0-standalone.jar"; DestDir: "{app}\bin"
Source: "Output\configure-{#MyInstallerBaseName}.exe"; DestDir: "{app}\bin"
Source: "profiles.clj"; DestDir: "{%LEIN_HOME|{%USERPROFILE}\.lein}"; Flags: onlyifdoesntexist
#endif
[Icons]
#ifndef configure
Name: "{group}\Clojure REPL"; Filename: "{app}\bin\lein.bat"; WorkingDir: "{userdocs}"; Parameters: "repl"; IconFilename: "{sys}\shell32.dll"; IconIndex: 133
Name: "{group}\Edit profiles.clj"; Filename: "{%LEIN_HOME|{%USERPROFILE}\.lein}\profiles.clj"; Flags: excludefromshowinnewinstall; IconFilename: "{sys}\shell32.dll"; IconIndex: 69
Name: "{group}\Online help"; Filename: "{#MyAppURL}"; Flags: excludefromshowinnewinstall; IconFilename: "{sys}\shell32.dll"; IconIndex: 154
Name: "{group}\Configure Leiningen Installation"; Filename: "{app}\bin\configure-{#MyInstallerBaseName}.exe"; Flags: excludefromshowinnewinstall
#endif
[Run]
Filename: "{app}\bin\curl.exe"; WorkingDir: "{app}\bin"; Parameters: """https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat"" -L -o lein.bat"; StatusMsg: "Downloading 'lein.bat'"; Flags: runasoriginaluser runminimized
Filename: "{cmd}"; WorkingDir: "{app}\bin"; Parameters: "/c set LEIN_JAVA_CMD={code:GetSelectedJdkPath} && ""{app}\bin\lein.bat"" self-install"; StatusMsg: "Downloading leiningen (lein self-install)"; Flags: runasoriginaluser runminimized
Filename: "{#MyAppURL}"; Description: "Open online help"; Flags: postinstall nowait skipifsilent shellexec
Filename: "{cmd}"; WorkingDir: "{userdocs}"; Parameters: "/c set LEIN_JAVA_CMD={code:GetSelectedJdkPath} && ""{app}\bin\lein.bat"" repl"; Description: "Run a Clojure REPL"; Flags: postinstall nowait skipifsilent
[UninstallDelete]
#ifndef configure
Type: files; Name: "{app}\bin\lein.bat"
Type: filesandordirs; Name: "{%LEIN_HOME|{%USERPROFILE}\.lein}\self-installs"
Type: filesandordirs; Name: "{%LEIN_HOME|{%USERPROFILE}\.lein}\indices"
#endif
[Code]
const
FileAssocJarName = 'file-assoc-in-0.1.0-standalone.jar';
var
JdkCount : Integer;
JdkVersions : TArrayOfString;
Jdk64s : TArrayOfBoolean;
JdkPaths : TArrayOfString;
JdkIndexes : TArrayOfInteger;
JdkPage : TInputOptionWizardPage;
CustomJdkPage : TInputDirWizardPage;
SelectedJdkIndex : Integer;
SelectedJdkPath : String;
PreviousJdkPath : String;
PreviousJdkIndex : Integer;
CustomJdkIndex : Integer;
function GetSelectedJdkPath(Param: String): String;
begin
Result := SelectedJdkPath;
end;
function IsInstalled(): Boolean;
begin
Result := RegValueExists(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{450F3BB7-7198-4401-A147-BDA0BECF6A3A}_is1', 'UninstallString');
end;
procedure PopulateJdks();
var
JavaVersions : TArrayOfString;
JavaPath : String;
I, J, JI : Integer;
JavaCount : Integer;
begin
JavaCount := 0;
if IsWin64() then
begin
if RegGetSubkeyNames(HKEY_LOCAL_MACHINE_64, 'SOFTWARE\JavaSoft\Java Development Kit', JavaVersions) then
begin
JavaCount := JavaCount + GetArrayLength(JavaVersions);
end
end
if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, 'SOFTWARE\JavaSoft\Java Development Kit', JavaVersions) then
begin
JavaCount := JavaCount + GetArrayLength(JavaVersions);
end
SetArrayLength(JdkVersions, JavaCount);
SetArrayLength(Jdk64s, JavaCount);
SetArrayLength(JdkPaths, JavaCount);
SetArrayLength(JdkIndexes, JavaCount);
JI := 0;
if IsWin64() then
begin
if RegGetSubkeyNames(HKEY_LOCAL_MACHINE_64, 'SOFTWARE\JavaSoft\Java Development Kit', JavaVersions) then
begin
for I := 0 to GetArrayLength(JavaVersions)-1 do
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE_64, 'SOFTWARE\JavaSoft\Java Development Kit\' + JavaVersions[I], 'JavaHome', JavaPath);
JdkVersions[JI] := JavaVersions[I];
Jdk64s[JI] := True;
JdkPaths[JI] := JavaPath;
JI := JI + 1;
end
end
end
if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, 'SOFTWARE\JavaSoft\Java Development Kit', JavaVersions) then
begin
for I := 0 to GetArrayLength(JavaVersions)-1 do
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\JavaSoft\Java Development Kit\' + JavaVersions[I], 'JavaHome', JavaPath);
JdkVersions[JI] := JavaVersions[I];
Jdk64s[JI] := False;
JdkPaths[JI] := JavaPath;
JI := JI + 1;
end
end
// filter out broken installs
for I := 0 to GetArrayLength(JdkVersions) - 1 do
begin
if not FileExists(AddBackslash(JdkPaths[I]) + 'bin\javac.exe') then
begin
JdkVersions[I] := '';
end
end
// filter out duplicates
for I := 0 to GetArrayLength(JdkVersions) - 1 do
begin
for J := 0 to GetArrayLength(JdkVersions) - 1 do
begin
if ((I <> J) and (JdkPaths[I] = JdkPaths[J]) and (JdkVersions[I] <> '') and (JdkVersions[J] <> '')) then
begin
if Length(JdkVersions[I]) < Length(JdkVersions[J]) then
begin
JdkVersions[I] := '';
end
else
begin
JdkVersions[J] := '';
end
end
end
end
JdkCount := 0;
for I := 0 to GetArrayLength(JdkVersions) - 1 do
begin
if JdkVersions[I] <> '' then
begin
JdkCount := JdkCount + 1;
end
end
PreviousJdkPath := GetEnv('LEIN_JAVA_CMD');
if not FileExists(PreviousJdkPath) then
begin
PreviousJdkPath := '';
end
end;
function InitializeSetup(): Boolean;
var
Button : Integer;
begin
#ifdef configure
if not IsInstalled() then
begin
MsgBox('Check that the application is installed, before attempting to configure the installation', mbInformation, MB_OK);
Result := False;
end
else
begin
#endif
PopulateJdks();
if JdkCount > 0 then
begin
Result := True;
end
else
begin
Button := MsgBox('An installed Java Development Kit could not be found automatically.' + Chr(13) + Chr(10) +
Chr(13) + Chr(10) +
'Ensure that you have downloaded and installed a JDK from:' + Chr(13) + Chr(10) +
'http://www.oracle.com/technetwork/java/javase/overview/index.html' + Chr(13) + Chr(10) +
Chr(13) + Chr(10) +
'Continue the installation?', mbError, MB_YESNO or MB_DEFBUTTON2);
Result := (Button = IDYES);
end
#ifdef configure
end
#endif
end;
procedure InitializeWizard();
var
I, JI : Integer;
BestJI : Integer;
BestVer : String;
Bitness : String;
Description : String;
begin
JdkPage := CreateInputOptionPage(wpSelectProgramGroup, 'Select JDK', '', 'Select the path to a Java Development Kit for Leiningen to use:', True, False);
BestJI := -2;
BestVer := '';
JI := 0;
for I := 0 to GetArrayLength(JdkVersions)-1 do
begin
if (JdkVersions[I] <> '') then
begin
JdkIndexes[JI] := I;
if Jdk64s[I] then
begin
Bitness := '64-bit';
end
else
begin
Bitness := '32-bit';
end
Description := Bitness + ' JDK ' + JdkVersions[I] + ' ( ' + JdkPaths[I] + ' )';
// Set the default as the JDK with the highest version, preferring 64-bit if available
if (CompareText(JdkVersions[I] + '_' + Bitness, BestVer)) >= 0 then
begin
BestVer := Description;
BestJI := JI;
end
JdkPage.Add(Description);
JI := JI + 1;
end
end
if (PreviousJdkPath <> '') then
begin
PreviousJdkIndex := JI;
JI := JI + 1;
JdkPage.Add('Previous location. ( ' + PreviousJdkPath + ' )');
JdkPage.SelectedValueIndex := PreviousJdkIndex;
end
else if BestJI <> -2 then
begin
PreviousJdkIndex := -3;
JdkPage.SelectedValueIndex := BestJI;
end
CustomJdkIndex := JI;
JdkPage.Add('Custom location...');
CustomJdkPage := CreateInputDirPage(JdkPage.ID, 'Custom JDK Location', '', 'Specify the location of an installed JDK:', False, '');
CustomJdkPage.Add('');
end;
Procedure SetSelectedJdkLocation();
begin
if JdkPage.SelectedValueIndex = CustomJdkIndex then
begin
SelectedJdkPath := RemoveQuotes(AddBackslash(CustomJdkPage.Values[0]) + 'bin\java.exe');
end
else if JdkPage.SelectedValueIndex = PreviousJdkIndex then
begin
SelectedJdkPath := RemoveQuotes(PreviousJdkPath);
end
else
begin
SelectedJdkPath := RemoveQuotes(AddBackslash(JdkPaths[SelectedJdkIndex]) + 'bin\java.exe');
end
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if CurPageId = CustomJdkPage.ID then
begin
if FileExists(AddBackslash(CustomJdkPage.Values[0]) + 'bin\java.exe') then
begin
SetSelectedJdkLocation();
end
else
begin
MsgBox('The specified location does not appear to contain a JDK', mbError, MB_OK);
Result := False;
end
end
else if CurPageId = JdkPage.ID then
begin
if JdkPage.SelectedValueIndex = -1 then
begin
Result := False;
end
else
begin
if JdkPage.SelectedValueIndex <> CustomJdkIndex then
begin
SelectedJdkIndex := JdkIndexes[JdkPage.SelectedValueIndex];
SetSelectedJdkLocation();
end
end
end
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
if (PageID = CustomJdkPage.ID) and (JdkPage.SelectedValueIndex <> (JdkPage.CheckListBox.Items.Count - 1)) then
begin
Result := True;
end
else
begin
Result := False;
end
end;
function AppendToPath(OldPath, NewPath: String): String;
var
Path: String;
begin
Path := OldPath;
if Pos(NewPath, Path) = 0 then
begin
if Length(Path) > 0 then
begin
Path := Path + ';';
end
Path := Path + NewPath;
end
Result := Path;
end;
function SetProfileJavaCmd(JavaPath: String): Boolean;
var
ProfilesPath: String;
AssocArgs: String;
ResultCode: Integer;
ResultMsg: String;
Success: Boolean;
begin
ProfilesPath := AddBackslash(ExpandConstant('{%LEIN_HOME|{%USERPROFILE}\.lein}')) + 'profiles.clj';
AssocArgs := '-jar ' + AddQuotes(AddBackslash(ExpandConstant('{app}\bin')) + FileAssocJarName) + ' ' +
AddQuotes(ProfilesPath) + ' ' +
'"[:user :java-cmd]"' + ' ' +
AddQuotes(JavaPath);
Log('Assoc Command: ' + JavaPath + ' ' + AssocArgs);
Success := Exec(JavaPath, AssocArgs,
ExpandConstant('{app}\bin'), SW_SHOWMINIMIZED, ewWaitUntilTerminated, ResultCode);
if Success and (ResultCode = 0) then
begin
Log('Updated profile');
end
else
begin
if Success then
begin
ResultMsg := 'Ran';
end
else
begin
ResultMsg := SysErrorMessage(ResultCode);
end
Log('Failed to update profile: ' + IntToStr(ResultCode));
MsgBox('Failed to update file: ' + ProfilesPath + chr(13) + chr(10) +
'Ensure that :java-cmd is set to: ' + AddQuotes(JavaPath) + ' in your :user profile.' + chr(13) + chr(10) +
'Result: ' + ResultMsg + '; Code: ' + IntToStr(ResultCode),
mbError, MB_OK);
end
Result := Success;
end;
function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
var
InstallInfo : String;
begin
if (MemoDirInfo <> '') then
begin
InstallInfo := MemoDirInfo;
end
else
begin
InstallInfo := 'Install location:' + NewLine + Space + ExpandConstant('{app}') + NewLine;
end
Result := MemoUserInfoInfo +
InstallInfo +
MemoTypeInfo +
MemoComponentsInfo +
MemoGroupInfo +
MemoTasksInfo +
NewLine + 'JDK Path:' + NewLine + Space + SelectedJdkPath;
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
AppPath: String;
JavaPath: String;
Path: String;
begin
if CurStep = ssPostInstall then
begin
if not RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then
begin
Path := '';
end
Log('Original PATH: ' + Path);
AppPath := ExpandConstant('{app}\bin');
Log('App Path: ' + AppPath);
Path := AppendToPath(Path, AppPath);
Log('Updated PATH: ' + Path);
RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path);
Log('PATH changed');
JavaPath := RemoveQuotes(SelectedJdkPath);
Log('Java Path: ' + JavaPath);
RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'LEIN_JAVA_CMD', JavaPath);
Log('Set LEIN_JAVA_CMD: ' + JavaPath);
SetProfileJavaCmd(JavaPath);
end
end;
#ifndef configure
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
AppPath: String;
Path: String;
begin
if CurUninstallStep = usUninstall then
begin
if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then
begin
Log('Original PATH: ' + Path);
AppPath := ExpandConstant('{app}\bin');
Log('App Path: ' + AppPath);
if Pos(AppPath, Path) <> 0 then
begin
StringChangeEx(Path, ';' + AppPath, '', True);
StringChangeEx(Path, AppPath + ';', '', True);
StringChangeEx(Path, AppPath, '', True);
end
Log('Updated PATH: ' + Path);
RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path);
Log('PATH changed');
end
RegDeleteValue(HKEY_CURRENT_USER, 'Environment', 'LEIN_JAVA_CMD');
Log('Removed LEIN_JAVA_CMD');
end
end;
#endif