diff options
Diffstat (limited to 'installer')
-rw-r--r-- | installer/non-ui-blocking-exec.iss | 138 | ||||
-rw-r--r-- | installer/opentrack-installer.iss | 94 |
2 files changed, 231 insertions, 1 deletions
diff --git a/installer/non-ui-blocking-exec.iss b/installer/non-ui-blocking-exec.iss new file mode 100644 index 00000000..6eec259d --- /dev/null +++ b/installer/non-ui-blocking-exec.iss @@ -0,0 +1,138 @@ +[Code] +{ + Exec Helper for executing commands without blocking the InnoSetup GUI + + ---- + + The main procedure is NonUiBlockingExec(). + Your GUI will remain responsive during the operation. + + Initially written for 7zip by Rik and Jens A. Koch (@jakoch) on StackOverflow: + http://stackoverflow.com/questions/32256432/how-to-execute-7zip-without-blocking-the-innosetup-ui + + ---- + + Usage: + + 1. Include this ISS with + + // #include "..\some\where\non-ui-blocking-exec.iss" + + 2. extract your files using NonUiBlockingExec(command, params); in the [Code] section. +} + +#IFDEF UNICODE + #DEFINE AW "W" +#ELSE + #DEFINE AW "A" +#ENDIF + +// --- Start "ShellExecuteEx" Helper + +const + WAIT_TIMEOUT = $00000102; + SEE_MASK_NOCLOSEPROCESS = $00000040; + INFINITE = $FFFFFFFF; { Infinite timeout } + +type + TShellExecuteInfo = record + cbSize: DWORD; + fMask: Cardinal; + Wnd: HWND; + lpVerb: string; + lpFile: string; + lpParameters: string; + lpDirectory: string; + nShow: Integer; + hInstApp: THandle; + lpIDList: DWORD; + lpClass: string; + hkeyClass: THandle; + dwHotKey: DWORD; + hMonitor: THandle; + hProcess: THandle; + end; + +function ShellExecuteEx(var lpExecInfo: TShellExecuteInfo): BOOL; + external 'ShellExecuteEx{#AW}@shell32.dll stdcall'; +function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; + external 'WaitForSingleObject@kernel32.dll stdcall'; +function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall'; + +// --- End "ShellExecuteEx" Helper + +// --- Start "Application.ProcessMessage" Helper +{ + InnoSetup does not provide Application.ProcessMessage(). + This is "generic" code to recreate a "Application.ProcessMessages"-ish procedure, + using the WinAPI function PeekMessage(), TranslateMessage() and DispatchMessage(). +} +type + TMsg = record + hwnd: HWND; + message: UINT; + wParam: Longint; + lParam: Longint; + time: DWORD; + pt: TPoint; + end; + +const + PM_REMOVE = 1; + +function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall'; +function TranslateMessage(const lpMsg: TMsg): BOOL; external 'TranslateMessage@user32.dll stdcall'; +function DispatchMessage(const lpMsg: TMsg): Longint; external 'DispatchMessageA@user32.dll stdcall'; + +procedure AppProcessMessage; +var + Msg: TMsg; +begin + while PeekMessage(Msg, WizardForm.Handle, 0, 0, PM_REMOVE) do begin + TranslateMessage(Msg); + DispatchMessage(Msg); + end; +end; + +// --- End "Application.ProcessMessage" Helper + +procedure NonUiBlockingExec(command: String; params: String); +var + ExecInfo: TShellExecuteInfo; // info object for ShellExecuteEx() +begin + // source and targetdir might contain {tmp} or {app} constant, so expand/resolve it to path names + command := ExpandConstant(command); + params := ExpandConstant(params); + + // prepare information about the application being executed by ShellExecuteEx() + ExecInfo.cbSize := SizeOf(ExecInfo); + ExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS; + ExecInfo.Wnd := 0; + ExecInfo.lpFile := command; + ExecInfo.lpParameters := params; + ExecInfo.nShow := SW_HIDE; + + { + The executable is executed via ShellExecuteEx() + Then the installer uses a while loop with the condition + WaitForSingleObject and a very minimal timeout + to execute AppProcessMessage. + + AppProcessMessage is itself a helper function, because + Innosetup does not provide Application.ProcessMessages(). + Its job is to be the message pump to the InnoSetup GUI. + + This trick makes the window responsive/dragable again, + while the extraction is done in the background. + } + + if ShellExecuteEx(ExecInfo) then + begin + while WaitForSingleObject(ExecInfo.hProcess, 100) = WAIT_TIMEOUT + do begin + AppProcessMessage; + WizardForm.Refresh(); + end; + CloseHandle(ExecInfo.hProcess); + end; +end;
\ No newline at end of file diff --git a/installer/opentrack-installer.iss b/installer/opentrack-installer.iss index c29bc4a3..cf963bed 100644 --- a/installer/opentrack-installer.iss +++ b/installer/opentrack-installer.iss @@ -8,6 +8,8 @@ #define MyAppURL "http://github.com/opentrack/opentrack" #define MyAppExeName "opentrack.exe" +#include "non-ui-blocking-exec.iss" + [Setup] ; NOTE: The value of AppId uniquely identifies this application. ; Do not use the same AppId value in installers for other applications. @@ -49,4 +51,94 @@ Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon [Run] -Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}" +Filename: "timeout.exe"; Parameters: "/t 0"; Flags: runhidden; StatusMsg: Installing RealSense Runtime. This may take several minutes.; Check: RSCameraDriverDetectedAndEulaAccepted +Filename: "{app}\{#MyAppExeName}"; Flags: nowait postinstall skipifsilent; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; + +[Code] +var + EulaAccepted:Boolean; + RSCameraDriverDetected:Boolean; + EULAPage: TOutputMsgMemoWizardPage; + EULAAcceptRadioButton: TNewRadioButton; + EULARefuseRadioButton: TNewRadioButton; + +function IsRSCameraDriverPresent():Boolean; +var + Version:String; +begin + result := RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\Intel\RSSDK\Components\ivcam', + 'Version', Version) or RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\Wow6432Node\Intel\RSDCM\SR300', + 'Version', Version) +end; + +procedure EULAAcceptRefuseButtonStateUpdated(Sender: TObject); +begin + EulaAccepted := EULAAcceptRadioButton.Checked +end; + + +function RSCameraDriverDetectedAndEulaAccepted():Boolean; +begin +result := RSCameraDriverDetected and EulaAccepted; +end; + +procedure DoPostInstall(); +var + Version: String; + ExecInfo: TShellExecuteInfo; +begin +if RSCameraDriverDetectedAndEulaAccepted then + begin + NonUiBlockingExec(ExpandConstant('{app}\contrib\intel_rs_sdk_runtime_websetup_8.0.24.6528.exe'), + '--silent --no-progress --acceptlicense=yes --front --finstall=core,face3d --fnone=all'); + end +end; + +procedure CurStepChanged(CurStep: TSetupStep); + begin + if CurStep = ssPostInstall then + begin + DoPostInstall() + end +end; + +procedure InitializeWizard(); +var + EULAText: String; +begin + +EulaAccepted := false +RSCameraDriverDetected := IsRSCameraDriverPresent() + +if RSCameraDriverDetected then + begin + ExtractTemporaryFile('RS_EULA.rtf'); + if LoadStringFromFile(ExpandConstant('{tmp}\RS_EULA.rtf'), EULAText) then + begin + EULAPage := CreateOutputMsgMemoPage(wpLicense, + 'Information', 'Intel RealSense End-User License agreement', + 'Opentrack may use the Intel RealSense SDK Runtime on your compatible system. To get it installed, please accept its EULA:', + EULAText); + EULAPage.RichEditViewer.Height := ScaleY(148); + EULAAcceptRadioButton := TNewRadioButton.Create(EULAPage); + EULAAcceptRadioButton.Left := EULAPage.RichEditViewer.Left; + EULAAcceptRadioButton.Top := EULAPage.Surface.ClientHeight - ScaleY(41); + EULAAcceptRadioButton.Width := EULAPage.RichEditViewer.Width; + EULAAcceptRadioButton.Parent := EULAPage.Surface; + EULAAcceptRadioButton.Caption := SetupMessage(msgLicenseAccepted); + EULARefuseRadioButton := TNewRadioButton.Create(EULAPage); + EULARefuseRadioButton.Left := EULAPage.RichEditViewer.Left; + EULARefuseRadioButton.Top := EULAPage.Surface.ClientHeight - ScaleY(21); + EULARefuseRadioButton.Width := EULAPage.RichEditViewer.Width; + EULARefuseRadioButton.Parent := EULAPage.Surface; + EULARefuseRadioButton.Caption := SetupMessage(msgLicenseNotAccepted); + + // Set the states and event handlers + EULAAcceptRadioButton.OnClick := @EULAAcceptRefuseButtonStateUpdated; + EULARefuseRadioButton.OnClick := @EULAAcceptRefuseButtonStateUpdated; + EULARefuseRadioButton.Checked := true; + EulaAccepted := EULAAcceptRadioButton.Checked + //TODO: if camera is detected, activate RS EULA page and RSSDK install, save if it was accepted or not. + end + end +end;
\ No newline at end of file |