1
1
; -- CEdev installation script --
2
2
3
3
[Setup]
4
- AppName = TI - 84 + CE C SDK
4
+ AppName = CE C Toolchain
5
5
AppVersion = {#APP_VERSION}
6
6
DefaultDirName = {sd} \CEdev
7
7
DefaultGroupName = CEdev
@@ -23,6 +23,24 @@ const SystemEnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\E
23
23
const UserEnvironmentKey = ' Environment' ;
24
24
const CEDEVKey = ' CEDEV' ;
25
25
26
+ type
27
+ TDependency = record
28
+ Filename: String;
29
+ Parameters: String;
30
+ Title: String;
31
+ URL: String;
32
+ Checksum: String;
33
+ ForceSuccess: Boolean;
34
+ InstallClean: Boolean;
35
+ RebootAfter: Boolean;
36
+ end ;
37
+ InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);
38
+ var
39
+ MemoInstallInfo: String;
40
+ Dependencies: array of TDependency;
41
+ DelayedReboot, ForceX86: Boolean;
42
+ DownloadPage: TDownloadWizardPage;
43
+
26
44
procedure EnvAddPath (Path: string);
27
45
var
28
46
Paths: string;
@@ -71,5 +89,275 @@ begin
71
89
end ;
72
90
73
91
92
+ // https://github.com/DomGries/InnoDependencyInstaller
93
+ // code to download and install Microsoft Visual C++ Runtime as needed.
94
+ procedure AddDependency (const Filename, Parameters, Title, URL, Checksum: String; const ForceSuccess, InstallClean, RebootAfter: Boolean);
95
+ var
96
+ Dependency: TDependency;
97
+ I: Integer;
98
+ begin
99
+ MemoInstallInfo := MemoInstallInfo + #13 #10 + ' %1' + Title;
100
+ Dependency.Filename := Filename;
101
+ Dependency.Parameters := Parameters;
102
+ Dependency.Title := Title;
103
+ if FileExists(ExpandConstant(' {tmp}{\}' ) + Filename) then begin
104
+ Dependency.URL := ' ' ;
105
+ end else begin
106
+ Dependency.URL := URL;
107
+ end ;
108
+ Dependency.Checksum := Checksum;
109
+ Dependency.ForceSuccess := ForceSuccess;
110
+ Dependency.InstallClean := InstallClean;
111
+ Dependency.RebootAfter := RebootAfter;
112
+ I := GetArrayLength(Dependencies);
113
+ SetArrayLength(Dependencies, I + 1 );
114
+ Dependencies[I] := Dependency;
115
+ end ;
116
+ function IsPendingReboot : Boolean;
117
+ var
118
+ Value : String;
119
+ begin
120
+ Result := RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, ' SYSTEM\CurrentControlSet\Control\Session Manager' , ' PendingFileRenameOperations' , Value ) or
121
+ (RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, ' SYSTEM\CurrentControlSet\Control\Session Manager' , ' SetupExecute' , Value ) and (Value <> ' ' ));
122
+ end ;
123
+ function InstallProducts : InstallResult;
124
+ var
125
+ ResultCode, I, ProductCount: Integer;
126
+ begin
127
+ Result := InstallSuccessful;
128
+ ProductCount := GetArrayLength(Dependencies);
129
+ MemoInstallInfo := SetupMessage(msgReadyMemoTasks);
130
+ if ProductCount > 0 then begin
131
+ DownloadPage.Show;
132
+ for I := 0 to ProductCount - 1 do begin
133
+ if Dependencies[I].InstallClean and (DelayedReboot or IsPendingReboot) then begin
134
+ Result := InstallRebootRequired;
135
+ break;
136
+ end ;
137
+ DownloadPage.SetText(Dependencies[I].Title, ' ' );
138
+ DownloadPage.SetProgress(I + 1 , ProductCount);
139
+ while True do begin
140
+ ResultCode := 0 ;
141
+ if ShellExec(' ' , ExpandConstant(' {tmp}{\}' ) + Dependencies[I].Filename, Dependencies[I].Parameters, ' ' , SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin
142
+ if Dependencies[I].RebootAfter then begin
143
+ // delay reboot after install if we installed the last dependency anyways
144
+ if I = ProductCount - 1 then begin
145
+ DelayedReboot := True;
146
+ end else begin
147
+ Result := InstallRebootRequired;
148
+ MemoInstallInfo := Dependencies[I].Title;
149
+ end ;
150
+ break;
151
+ end else if (ResultCode = 0 ) or Dependencies[I].ForceSuccess then begin
152
+ break;
153
+ end else if ResultCode = 3010 then begin
154
+ // Windows Installer ResultCode 3010: ERROR_SUCCESS_REBOOT_REQUIRED
155
+ DelayedReboot := True;
156
+ break;
157
+ end ;
158
+ end ;
159
+ case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependencies[I].Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
160
+ IDABORT: begin
161
+ Result := InstallError;
162
+ MemoInstallInfo := MemoInstallInfo + #13 #10 + ' ' + Dependencies[I].Title;
163
+ break;
164
+ end ;
165
+ IDIGNORE: begin
166
+ MemoInstallInfo := MemoInstallInfo + #13 #10 + ' ' + Dependencies[I].Title;
167
+ break;
168
+ end ;
169
+ end ;
170
+ end ;
171
+ if Result <> InstallSuccessful then begin
172
+ break;
173
+ end ;
174
+ end ;
175
+ DownloadPage.Hide;
176
+ end ;
177
+ end ;
178
+ // Inno Setup event functions
179
+ procedure InitializeWizard ;
180
+ begin
181
+ DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil );
182
+ end ;
183
+ function PrepareToInstall (var NeedsRestart: Boolean): String;
184
+ var
185
+ I: Integer;
186
+ begin
187
+ DelayedReboot := False;
188
+ case InstallProducts of
189
+ InstallError: begin
190
+ Result := MemoInstallInfo;
191
+ end ;
192
+ InstallRebootRequired: begin
193
+ Result := MemoInstallInfo;
194
+ NeedsRestart := True;
195
+ // write into the registry that the installer needs to be executed again after restart
196
+ RegWriteStringValue(HKEY_CURRENT_USER, ' SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' , ' InstallBootstrap' , ExpandConstant(' {srcexe}' ));
197
+ end ;
198
+ end ;
199
+ end ;
200
+ function NeedRestart : Boolean;
201
+ begin
202
+ Result := DelayedReboot;
203
+ end ;
204
+ function UpdateReadyMemo (const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
205
+ begin
206
+ Result := ' ' ;
207
+ if MemoUserInfoInfo <> ' ' then begin
208
+ Result := Result + MemoUserInfoInfo + Newline + NewLine;
209
+ end ;
210
+ if MemoDirInfo <> ' ' then begin
211
+ Result := Result + MemoDirInfo + Newline + NewLine;
212
+ end ;
213
+ if MemoTypeInfo <> ' ' then begin
214
+ Result := Result + MemoTypeInfo + Newline + NewLine;
215
+ end ;
216
+ if MemoComponentsInfo <> ' ' then begin
217
+ Result := Result + MemoComponentsInfo + Newline + NewLine;
218
+ end ;
219
+ if MemoGroupInfo <> ' ' then begin
220
+ Result := Result + MemoGroupInfo + Newline + NewLine;
221
+ end ;
222
+ if MemoTasksInfo <> ' ' then begin
223
+ Result := Result + MemoTasksInfo;
224
+ end ;
225
+ if MemoInstallInfo <> ' ' then begin
226
+ if MemoTasksInfo = ' ' then begin
227
+ Result := Result + SetupMessage(msgReadyMemoTasks);
228
+ end ;
229
+ Result := Result + FmtMessage(MemoInstallInfo, [Space]);
230
+ end ;
231
+ end ;
232
+ function NextButtonClick (const CurPageID: Integer): Boolean;
233
+ var
234
+ I, ProductCount: Integer;
235
+ Retry: Boolean;
236
+ begin
237
+ Result := True;
238
+ if (CurPageID = wpReady) and (MemoInstallInfo <> ' ' ) then begin
239
+ DownloadPage.Show;
240
+ ProductCount := GetArrayLength(Dependencies);
241
+ for I := 0 to ProductCount - 1 do begin
242
+ if Dependencies[I].URL <> ' ' then begin
243
+ DownloadPage.Clear;
244
+ DownloadPage.Add(Dependencies[I].URL, Dependencies[I].Filename, Dependencies[I].Checksum);
245
+ Retry := True;
246
+ while Retry do begin
247
+ Retry := False;
248
+ try
249
+ DownloadPage.Download;
250
+ except
251
+ if GetExceptionMessage = SetupMessage(msgErrorDownloadAborted) then begin
252
+ Result := False;
253
+ I := ProductCount;
254
+ end else begin
255
+ case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
256
+ IDABORT: begin
257
+ Result := False;
258
+ I := ProductCount;
259
+ end ;
260
+ IDRETRY: begin
261
+ Retry := True;
262
+ end ;
263
+ end ;
264
+ end ;
265
+ end ;
266
+ end ;
267
+ end ;
268
+ end ;
269
+ DownloadPage.Hide;
270
+ end ;
271
+ end ;
272
+ // architecture helper functions
273
+ function IsX64 : Boolean;
274
+ begin
275
+ Result := not ForceX86 and Is64BitInstallMode;
276
+ end ;
277
+ function GetString (const x86, x64: String): String;
278
+ begin
279
+ if IsX64 then begin
280
+ Result := x64;
281
+ end else begin
282
+ Result := x86;
283
+ end ;
284
+ end ;
285
+ function GetArchitectureSuffix : String;
286
+ begin
287
+ Result := GetString(' ' , ' _x64' );
288
+ end ;
289
+ function GetArchitectureTitle : String;
290
+ begin
291
+ Result := GetString(' (x86)' , ' (x64)' );
292
+ end ;
293
+ function CompareVersion (const Version1, Version2: String): Integer;
294
+ var
295
+ Position, Number1, Number2: Integer;
296
+ begin
297
+ Result := 0 ;
298
+ while (Version1 <> ' ' ) or (Version2 <> ' ' ) do begin
299
+ Position := Pos(' .' , Version1);
300
+ if Position > 0 then begin
301
+ Number1 := StrToIntDef(Copy(Version1, 1 , Position - 1 ), 0 );
302
+ Delete(Version1, 1 , Position);
303
+ end else if Version1 <> ' ' then begin
304
+ Number1 := StrToIntDef(Version1, 0 );
305
+ Version1 := ' ' ;
306
+ end else begin
307
+ Number1 := 0 ;
308
+ end ;
309
+ Position := Pos(' .' , Version2);
310
+ if Position > 0 then begin
311
+ Number2 := StrToIntDef(Copy(Version2, 1 , Position - 1 ), 0 );
312
+ Delete(Version2, 1 , Position);
313
+ end else if Version2 <> ' ' then begin
314
+ Number2 := StrToIntDef(Version2, 0 );
315
+ Version2 := ' ' ;
316
+ end else begin
317
+ Number2 := 0 ;
318
+ end ;
319
+ if Number1 < Number2 then begin
320
+ Result := -1 ;
321
+ break;
322
+ end else if Number1 > Number2 then begin
323
+ Result := 1 ;
324
+ break;
325
+ end ;
326
+ end ;
327
+ end ;
328
+
329
+ function MsiEnumRelatedProducts (UpgradeCode: String; Reserved, Index: DWORD; ProductCode: String): Integer;
330
+ external ' MsiEnumRelatedProductsW@msi.dll stdcall' ;
331
+ function MsiGetProductInfo (ProductCode, PropertyName, Value : String; var ValueSize: DWORD): Integer;
332
+ external ' MsiGetProductInfoW@msi.dll stdcall' ;
333
+ function IsMsiProductInstalled (const UpgradeCode, MinVersion: String): Boolean;
334
+ var
335
+ ProductCode, Version: String;
336
+ ValueSize: DWORD;
337
+ begin
338
+ SetLength(ProductCode, 39 );
339
+ Result := False;
340
+ if MsiEnumRelatedProducts(UpgradeCode, 0 , 0 , ProductCode) = 0 then begin
341
+ SetLength(Version, 39 );
342
+ ValueSize := Length(Version);
343
+ if MsiGetProductInfo(ProductCode, ' VersionString' , Version, ValueSize) = 0 then begin
344
+ Result := CompareVersion(Version, MinVersion) >= 0 ;
345
+ end ;
346
+ end ;
347
+ end ;
348
+
349
+ function InitializeSetup : Boolean;
350
+ var
351
+ Version: String;
352
+ begin
74
353
354
+ if not IsMsiProductInstalled(GetString(' {65E5BD06-6392-3027-8C26-853107D3CF1A}' , ' {36F68A90-239C-34DF-B58C-64B30153CE35}' ), ' 14.28.29325' ) then begin
355
+ AddDependency(' vcredist2019' + GetArchitectureSuffix + ' .exe' ,
356
+ ' /install /quiet /norestart' ,
357
+ ' Visual C++ 2015-2019 Redistributable' + GetArchitectureTitle,
358
+ GetString(' https://aka.ms/vs/16/release/vc_redist.x86.exe' , ' https://aka.ms/vs/16/release/vc_redist.x64.exe' ),
359
+ ' ' , False, False, False);
360
+ end ;
75
361
362
+ Result := True;
363
+ end ;
0 commit comments