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 | |
| 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')
| -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  | 
