#define MyAppName "Inventera Client" #define MyAppVersion "2.0" #define MyAppPublisher "Inventera" #define MyAppExeName "Inv_web Client.exe" #define RustDeskInstaller "installer\prerequisites\rustdesk.exe" [Setup] AppId={{6F0D1694-CACE-4F7D-97A2-BB01C240775B} AppName={#MyAppName} AppVersion={#MyAppVersion} AppPublisher={#MyAppPublisher} DefaultDirName={autopf}\{#MyAppName} DefaultGroupName={#MyAppName} PrivilegesRequired=admin UsePreviousAppDir=no UsePreviousGroup=no OutputDir=dist OutputBaseFilename=Inv_web_Client_Setup SetupIconFile=picture\ICON\icon_client.ico UninstallDisplayIcon={app}\{#MyAppExeName} Compression=lzma2 SolidCompression=yes WizardStyle=modern ArchitecturesAllowed=x64compatible ArchitecturesInstallIn64BitMode=x64compatible CloseApplications=yes RestartApplications=no DisableProgramGroupPage=yes DisableDirPage=yes DisableReadyPage=yes [Languages] Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" [Files] Source: "dist\Inv_web Client\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#RustDeskInstaller}"; DestDir: "{tmp}"; DestName: "rustdesk-installer.exe"; Flags: deleteafterinstall noencryption; Check: ShouldInstallRustDesk Source: "installer\configure_rustdesk.ps1"; DestDir: "{tmp}"; Flags: deleteafterinstall noencryption; Check: ShouldInstallRustDesk [InstallDelete] ; Remove shortcuts from releases whose target was inside the elevated ; administrator's LocalAppData. CloseApplications asks Restart Manager to ; close a legacy client before this known application folder is removed. Type: files; Name: "{commondesktop}\Inv_web Client.lnk" Type: filesandordirs; Name: "{commonprograms}\Inv_web Client" Type: filesandordirs; Name: "{localappdata}\Programs\Inv_web Client" [Icons] Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" [Run] ; The client configuration belongs to the interactive user who started Setup, ; not to the administrator whose credentials were entered in the UAC dialog. Filename: "{app}\{#MyAppExeName}"; Parameters: "--configure-only --server ""{code:GetServerAddress}"""; Flags: runhidden waituntilterminated runasoriginaluser Filename: "{app}\{#MyAppExeName}"; Description: "Запустить {#MyAppName}"; Flags: nowait postinstall skipifsilent runasoriginaluser [Code] var InstallModePage: TInputOptionWizardPage; RustDeskServerPage: TInputQueryWizardPage; RustDeskPasswordPage: TInputQueryWizardPage; ConnectionPage: TInputQueryWizardPage; function IsManualRustDeskMode: Boolean; begin Result := InstallModePage.SelectedValueIndex = 1; end; function ShouldInstallRustDesk: Boolean; begin Result := InstallModePage.SelectedValueIndex <> 2; end; procedure InitializeWizard; begin InstallModePage := CreateInputOptionPage( wpWelcome, 'Режим установки', 'Выберите состав установки', 'Клиент Inventera устанавливается во всех режимах.', True, False ); InstallModePage.Add('Автоматический режим с RustDesk'); InstallModePage.Add('Ручной режим с сервером RustDesk'); InstallModePage.Add('Установка без RustDesk (удалённого доступа)'); InstallModePage.SelectedValueIndex := 0; RustDeskServerPage := CreateInputQueryPage( InstallModePage.ID, 'Сервер RustDesk', 'Укажите параметры собственного сервера', 'Введите адреса серверов RustDesk и публичный ключ сервера.' ); RustDeskServerPage.Add('Сервер ID:', False); RustDeskServerPage.Add('Ретранслятор:', False); RustDeskServerPage.Add('Key:', False); RustDeskPasswordPage := CreateInputQueryPage( RustDeskServerPage.ID, 'Фиксированный пароль RustDesk', 'Настройте постоянный пароль удалённого доступа', 'Оставьте поле пустым, чтобы пропустить этот шаг и не задавать пароль.' ); RustDeskPasswordPage.Add('Фиксированный пароль:', True); ConnectionPage := CreateInputQueryPage( RustDeskPasswordPage.ID, 'Подключение к серверу', 'Укажите параметры подключения клиента', 'Введите адрес сервера. Служебный токен будет настроен автоматически.' ); ConnectionPage.Add('Адрес сервера:', False); end; function ShouldSkipPage(PageID: Integer): Boolean; begin Result := False; if (PageID = RustDeskServerPage.ID) and (not IsManualRustDeskMode) then begin Result := True; Exit; end; if (PageID = RustDeskPasswordPage.ID) and (not ShouldInstallRustDesk) then Result := True; end; function ContainsUnsafeCommandLineCharacters(const Value: String): Boolean; begin Result := (Pos('"', Value) > 0) or (Pos(#13, Value) > 0) or (Pos(#10, Value) > 0); end; function NextButtonClick(CurPageID: Integer): Boolean; begin Result := True; if CurPageID = RustDeskServerPage.ID then begin if Trim(RustDeskServerPage.Values[0]) = '' then begin MsgBox('Укажите сервер ID RustDesk.', mbError, MB_OK); Result := False; Exit; end; if Trim(RustDeskServerPage.Values[1]) = '' then begin MsgBox('Укажите ретранслятор RustDesk.', mbError, MB_OK); Result := False; Exit; end; if Trim(RustDeskServerPage.Values[2]) = '' then begin MsgBox('Укажите публичный Key сервера RustDesk.', mbError, MB_OK); Result := False; Exit; end; if ContainsUnsafeCommandLineCharacters(RustDeskServerPage.Values[0]) or ContainsUnsafeCommandLineCharacters(RustDeskServerPage.Values[1]) or ContainsUnsafeCommandLineCharacters(RustDeskServerPage.Values[2]) then begin MsgBox('Параметры RustDesk не должны содержать кавычки или переносы строк.', mbError, MB_OK); Result := False; Exit; end; end; if CurPageID = RustDeskPasswordPage.ID then begin if ContainsUnsafeCommandLineCharacters(RustDeskPasswordPage.Values[0]) then begin MsgBox('Пароль RustDesk не должен содержать кавычки или переносы строк.', mbError, MB_OK); Result := False; end; Exit; end; if CurPageID <> ConnectionPage.ID then Exit; if Trim(ConnectionPage.Values[0]) = '' then begin MsgBox('Укажите адрес сервера.', mbError, MB_OK); Result := False; Exit; end; if ContainsUnsafeCommandLineCharacters(ConnectionPage.Values[0]) then begin MsgBox('Адрес сервера не должен содержать кавычки или переносы строк.', mbError, MB_OK); Result := False; end; end; function GetRustDeskMode(Param: String): String; begin if IsManualRustDeskMode then Result := 'manual' else Result := 'automatic'; end; function GetRustDeskIdServer(Param: String): String; begin Result := Trim(RustDeskServerPage.Values[0]); end; function GetRustDeskRelayServer(Param: String): String; begin Result := Trim(RustDeskServerPage.Values[1]); end; function GetRustDeskKey(Param: String): String; begin Result := Trim(RustDeskServerPage.Values[2]); end; function GetRustDeskPassword(Param: String): String; begin Result := RustDeskPasswordPage.Values[0]; end; function QuoteArgument(const Value: String): String; begin Result := '"' + Value + '"'; end; procedure CurStepChanged(CurStep: TSetupStep); var ExitCode: Integer; ConfigurationPath: String; ConfigurationText: String; ErrorPath: String; LogPath: String; ErrorLines: TArrayOfString; ErrorText: String; ExecSucceeded: Boolean; PowerShellPath: String; Parameters: String; begin if (CurStep <> ssPostInstall) or (not ShouldInstallRustDesk) then Exit; WizardForm.StatusLabel.Caption := 'Установка и настройка RustDesk...'; PowerShellPath := ExpandConstant( '{sys}\WindowsPowerShell\v1.0\powershell.exe' ); ConfigurationPath := ExpandConstant('{tmp}\rustdesk-options.ini'); ErrorPath := ExpandConstant('{tmp}\rustdesk-error.txt'); LogPath := ExpandConstant( '{commonappdata}\Inventera Client\rustdesk-install.log' ); DeleteFile(ErrorPath); ConfigurationText := 'Mode=' + GetRustDeskMode('') + #13#10 + 'IdServer=' + GetRustDeskIdServer('') + #13#10 + 'RelayServer=' + GetRustDeskRelayServer('') + #13#10 + 'Key=' + GetRustDeskKey('') + #13#10 + 'Password=' + GetRustDeskPassword('') + #13#10; if not SaveStringToFile(ConfigurationPath, ConfigurationText, False) then RaiseException('Не удалось подготовить параметры RustDesk.'); Parameters := '-NoProfile -NonInteractive -ExecutionPolicy Bypass -File ' + QuoteArgument(ExpandConstant('{tmp}\configure_rustdesk.ps1')) + ' ' + '-InstallerPath ' + QuoteArgument(ExpandConstant('{tmp}\rustdesk-installer.exe')) + ' ' + '-ConfigurationPath ' + QuoteArgument(ConfigurationPath) + ' ' + '-ErrorPath ' + QuoteArgument(ErrorPath); ExitCode := -1; ExecSucceeded := Exec( PowerShellPath, Parameters, '', SW_HIDE, ewWaitUntilTerminated, ExitCode ); DeleteFile(ConfigurationPath); if (not ExecSucceeded) or (ExitCode <> 0) then begin ErrorText := ''; if LoadStringsFromFile(ErrorPath, ErrorLines) and (GetArrayLength(ErrorLines) > 0) then ErrorText := ErrorLines[0]; DeleteFile(ErrorPath); if ErrorText <> '' then RaiseException( 'Не удалось установить или настроить RustDesk. Код ошибки: ' + IntToStr(ExitCode) + '.' + #13#10 + ErrorText ) else RaiseException( 'Не удалось установить или настроить RustDesk. Код ошибки: ' + IntToStr(ExitCode) + '.' + #13#10 + 'Подробный журнал: ' + LogPath ); end; DeleteFile(ErrorPath); end; function GetServerAddress(Param: String): String; begin Result := Trim(ConnectionPage.Values[0]); end;