diff options
author | Xavier Hallade <xavier.hallade@intel.com> | 2016-04-27 09:50:36 +0200 |
---|---|---|
committer | Xavier Hallade <xavier.hallade@intel.com> | 2016-04-27 09:50:36 +0200 |
commit | f3d62b23b02bb27cbb0f0f0302001f0710992df2 (patch) | |
tree | ada631f9bb767c2f55fd46b422cf83a1d2ba32fb /installer/non-ui-blocking-exec.iss | |
parent | fb7e86d02e1d9a15dedad048aa477c1985423057 (diff) |
installer: propose install of RealSense runtime on compatible systems
When an user installs opentrack on a system which has RealSense F200 or
SR300 camera drivers installed, the installer now proposes to install the
proper runtime after having displayed its EULA.
Diffstat (limited to 'installer/non-ui-blocking-exec.iss')
-rw-r--r-- | installer/non-ui-blocking-exec.iss | 138 |
1 files changed, 138 insertions, 0 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 |