@@ -25,7 +25,6 @@ Name: install_usb; Description: "Install Opal Kelly Front Panel USB driver for O
2525[Files]
2626Source : " ..\..\..\Build\Release\*" ; DestDir : " {app} " ; Flags : ignoreversion recursesubdirs ; BeforeInstall : UpdateProgress(0 );
2727Source : " ..\..\..\Build\Release\shared\*" ; DestDir : " {commonappdata} \Open Ephys\shared-api8" ; Flags : ignoreversion recursesubdirs ; BeforeInstall : UpdateProgress(55 );
28- Source : " vcredist_x64.exe" ; DestDir : {tmp} ; Flags : deleteafterinstall ; BeforeInstall : UpdateProgress(70 );
2928Source : " ..\..\DLLs\FrontPanelUSB-DriverOnly-4.5.5.exe" ; DestDir : {tmp} ; Flags : deleteafterinstall ; BeforeInstall : UpdateProgress(90 );
3029
3130[Icons]
@@ -34,45 +33,189 @@ Name: "{autodesktop}\Open Ephys"; Filename: "{app}\open-ephys.exe"; Tasks: deskt
3433Name : " {autoprograms}\Open Ephys" ; Filename : " {app} \open-ephys.exe"
3534
3635[Run]
37- Filename : " {tmp} \vcredist_x64.exe" ; Parameters : " /q /norestart /q:a /c:" " VCREDI~3.EXE /q:a /c:" " " " msiexec /i vcredist.msi /qn" " " " " " " ; Check : VCRedistNeedsInstall; WorkingDir : {app} ; StatusMsg : " Installing VC++ 2019 Redistributables..." ;
3836Filename : " {tmp} \FrontPanelUSB-DriverOnly-4.5.5.exe" ; StatusMsg : " Installing Front Panel USB driver..." ; Tasks: install_usb; Flags : skipifsilent
3937
4038[Code]
41- procedure UpdateProgress (Position: Integer);
39+ // types and variables
40+ type
41+ TDependency_Entry = record
42+ Filename: String;
43+ Parameters: String;
44+ Title: String;
45+ URL: String;
46+ Checksum: String;
47+ end ;
48+
49+ var
50+ Dependency_Memo: String;
51+ Dependency_Entry: TDependency_Entry;
52+ Dependency_Added: Boolean;
53+ Dependency_DownloadPage: TDownloadWizardPage;
54+
55+ procedure Dependency_Add (const Filename, Parameters, Title, URL, Checksum: String);
56+ var
57+ Dependency: TDependency_Entry;
4258begin
43- WizardForm.ProgressGauge.Position := Position * WizardForm.ProgressGauge.Max div 100 ;
59+ Dependency_Memo := Dependency_Memo + #13 #10 + ' %1' + Title;
60+
61+ Dependency.Filename := Filename;
62+ Dependency.Parameters := Parameters;
63+ Dependency.Title := Title;
64+
65+ if FileExists(ExpandConstant(' {tmp}{\}' ) + Filename) then begin
66+ Dependency.URL := ' ' ;
67+ end else begin
68+ Dependency.URL := URL;
69+ end ;
70+
71+ Dependency.Checksum := Checksum;
72+
73+ Dependency_Entry := Dependency;
74+ Dependency_Added := True;
4475end ;
4576
46- #IFDEF UNICODE
47- #DEFINE AW " W"
48- #ELSE
49- #DEFINE AW " A"
50- #ENDIF
51- type
52- INSTALLSTATE = Longint;
53- const
54- INSTALLSTATE_INVALIDARG = -2 ; // An invalid parameter was passed to the function.
55- INSTALLSTATE_UNKNOWN = -1 ; // The product is neither advertised or installed.
56- INSTALLSTATE_ADVERTISED = 1 ; // The product is advertised but not installed.
57- INSTALLSTATE_ABSENT = 2 ; // The product is installed for a different user.
58- INSTALLSTATE_DEFAULT = 5 ; // The product is installed for the current user.
77+ <event(' InitializeWizard' )>
78+ procedure Dependency_Internal1 ;
79+ begin
80+ Dependency_DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil );
81+ end ;
82+
83+ <event(' PrepareToInstall' )>
84+ function Dependency_Internal2 (var NeedsRestart: Boolean): String;
85+ var
86+ ResultCode: Integer;
87+ Retry: Boolean;
88+ begin
89+ if Dependency_Added then begin
90+ Dependency_DownloadPage.Show;
91+
92+ if Dependency_Entry.URL <> ' ' then begin
93+ Dependency_DownloadPage.Clear;
94+ Dependency_DownloadPage.Add(Dependency_Entry.URL, Dependency_Entry.Filename, Dependency_Entry.Checksum);
95+
96+ Retry := True;
97+ while Retry do begin
98+ Retry := False;
5999
60- // Visual C++ 2019 Redistributable 14.25.28508
61- VC_2019_REDIST_X86_MIN = ' {2BC3BD4D-FABA-4394-93C7-9AC82A263FE2}' ;
62- VC_2019_REDIST_X64_MIN = ' {EEA66967-97E2-4561-A999-5C22E3CDE428}' ;
100+ try
101+ Dependency_DownloadPage.Download;
102+ except
103+ if Dependency_DownloadPage.AbortedByUser then begin
104+ Result := Dependency_Entry.Title;
105+ end else begin
106+ case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
107+ IDABORT: begin
108+ Result := Dependency_Entry.Title;
109+ end ;
110+ IDRETRY: begin
111+ Retry := True;
112+ end ;
113+ end ;
114+ end ;
115+ end ;
116+ end ;
117+ end ;
63118
64- VC_2019_REDIST_X86_ADD = ' {0FA68574-690B-4B00-89AA-B28946231449} ' ;
65- VC_2019_REDIST_X64_ADD = ' {7D0B74C2-C3F8-4AF1-940F-CD79AB4B2DCE} ' ;
119+ if Result = ' ' then begin
120+ Dependency_DownloadPage.SetText(Dependency_Entry.Title, ' ' ) ;
66121
67- function MsiQueryProductState (szProduct: string): INSTALLSTATE;
68- external ' MsiQueryProductState{#AW}@msi.dll stdcall' ;
122+ while True do begin
123+ ResultCode := 0 ;
124+ if ShellExec(' ' , ExpandConstant(' {tmp}{\}' ) + Dependency_Entry.Filename, Dependency_Entry.Parameters, ' ' , SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin
69125
70- function VCVersionInstalled (const ProductID: string): Boolean;
126+ if ResultCode = 0 then begin // ERROR_SUCCESS (0)
127+ break;
128+ end ;
129+
130+ case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependency_Entry.Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
131+ IDABORT: begin
132+ Result := Dependency_Entry.Title;
133+ break;
134+ end ;
135+ IDIGNORE: begin
136+ break;
137+ end ;
138+ end ;
139+ end ;
140+ end ;
141+ end ;
142+
143+ Dependency_DownloadPage.Hide;
144+ end ;
145+ end ;
146+
147+ <event(' UpdateReadyMemo' )>
148+ function Dependency_Internal3 (const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
71149begin
72- Result := MsiQueryProductState(ProductID) = INSTALLSTATE_DEFAULT;
150+ Result := ' ' ;
151+ if MemoUserInfoInfo <> ' ' then begin
152+ Result := Result + MemoUserInfoInfo + Newline + NewLine;
153+ end ;
154+ if MemoDirInfo <> ' ' then begin
155+ Result := Result + MemoDirInfo + Newline + NewLine;
156+ end ;
157+ if MemoTypeInfo <> ' ' then begin
158+ Result := Result + MemoTypeInfo + Newline + NewLine;
159+ end ;
160+ if MemoComponentsInfo <> ' ' then begin
161+ Result := Result + MemoComponentsInfo + Newline + NewLine;
162+ end ;
163+ if MemoGroupInfo <> ' ' then begin
164+ Result := Result + MemoGroupInfo + Newline + NewLine;
165+ end ;
166+ if MemoTasksInfo <> ' ' then begin
167+ Result := Result + MemoTasksInfo;
168+ end ;
169+
170+ if Dependency_Memo <> ' ' then begin
171+ if MemoTasksInfo = ' ' then begin
172+ Result := Result + SetupMessage(msgReadyMemoTasks);
173+ end ;
174+ Result := Result + FmtMessage(Dependency_Memo, [Space]);
175+ end ;
73176end ;
74177
75- function VCRedistNeedsInstall : Boolean;
178+
179+ function Dependency_IsX64 : Boolean;
180+ begin
181+ Result := Is64BitInstallMode;
182+ end ;
183+
184+ function Dependency_String (const x86, x64: String): String;
185+ begin
186+ if Dependency_IsX64 then begin
187+ Result := x64;
188+ end else begin
189+ Result := x86;
190+ end ;
191+ end ;
192+
193+ function Dependency_ArchSuffix : String;
194+ begin
195+ Result := Dependency_String(' ' , ' _x64' );
196+ end ;
197+
198+ function Dependency_ArchTitle : String;
76199begin
77- Result := not (VCVersionInstalled(VC_2019_REDIST_X64_MIN));
200+ Result := Dependency_String(' (x86)' , ' (x64)' );
201+ end ;
202+
203+ procedure UpdateProgress (Position: Integer);
204+ begin
205+ WizardForm.ProgressGauge.Position := Position * WizardForm.ProgressGauge.Max div 100 ;
206+ end ;
207+
208+ function InitializeSetup : Boolean;
209+ begin
210+
211+ // https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist
212+ if not IsMsiProductInstalled(' {36F68A90-239C-34DF-B58C-64B30153CE35}' , PackVersionComponents(14 , 30 , 30704 , 0 )) then begin
213+ Dependency_Add(' vcredist2022_x64.exe' ,
214+ ' /passive /norestart' ,
215+ ' Visual C++ 2015-2022 Redistributable (x64)' ,
216+ ' https://aka.ms/vs/17/release/vc_redist.x64.exe' ,
217+ ' ' );
218+
219+ end ;
220+ Result := True;
78221end ;
0 commit comments