summaryrefslogtreecommitdiffhomepage
path: root/installer
diff options
context:
space:
mode:
authorXavier Hallade <xavier.hallade@intel.com>2016-04-27 09:50:36 +0200
committerXavier Hallade <xavier.hallade@intel.com>2016-04-27 09:50:36 +0200
commitf3d62b23b02bb27cbb0f0f0302001f0710992df2 (patch)
treeada631f9bb767c2f55fd46b422cf83a1d2ba32fb /installer
parentfb7e86d02e1d9a15dedad048aa477c1985423057 (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.iss138
-rw-r--r--installer/opentrack-installer.iss94
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