; JT2Go Installer with Prerequisite Checks ; Checks and installs VC++ Redistributables (x86/x64) and .NET Framework 4.8 ; Supports silent installation: /VERYSILENT /SUPPRESSMSGBOXES ; Version 1.1 [Setup] AppId={{A1B2C3D4-E5F6-7890-ABCD-EF1234567890} AppName=Siemens JT2Go AppVersion=2512 AppPublisher=WJDT AppPublisherURL=https://www.plm.automation.siemens.com DefaultDirName={autopf}\Siemens\JT2Go CreateAppDir=no PrivilegesRequired=admin OutputDir=.\Output OutputBaseFilename=JT2Go_Installer_v2512 SolidCompression=yes WizardStyle=modern SetupIconFile=gea-logo.ico WizardImageFile=patrick.bmp WizardSmallImageFile=patrick-sm.bmp DisableWelcomePage=no DisableDirPage=yes DisableProgramGroupPage=yes [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" [Messages] WelcomeLabel2=This will install Siemens JT2Go 2512 on your computer.%n%nThe installer will automatically check for and install the following prerequisites if needed:%n%n - Microsoft Visual C++ Redistributable (x86)%n - Microsoft Visual C++ Redistributable (x64)%n - Microsoft .NET Framework 4.8%n%nAdministrative privileges are required. [Files] ; Include all prerequisite installers Source: "VC_redist.x86.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall Source: "VC_redist.x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall Source: "NDP48-x86-x64-AllOS-ENU.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall Source: "JT2GoSetup.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall [Code] var ProgressPage: TOutputProgressWizardPage; PrereqPage: TOutputMsgMemoWizardPage; VCx86Needed, VCx64Needed, DotNetNeeded: Boolean; PrereqSummary: String; RebootRequired: Boolean; // ============================================ // Silent-aware message box wrapper // ============================================ procedure ShowMessage(Msg: String; MsgType: TMsgBoxType); begin if not WizardSilent then MsgBox(Msg, MsgType, MB_OK); end; // ============================================ // Registry Detection Functions // ============================================ // Check if VC++ 2015-2022 x64 Redistributable is installed function IsVCx64Installed: Boolean; var Installed: Cardinal; begin Result := False; // Check primary registry location for VC++ 2015-2022 x64 if RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Installed', Installed) then begin Result := (Installed = 1); end; // Also check newer registry path if not Result then begin if RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64', 'Installed', Installed) then begin Result := (Installed = 1); end; end; end; // Check if VC++ 2015-2022 x86 Redistributable is installed function IsVCx86Installed: Boolean; var Installed: Cardinal; begin Result := False; // On 64-bit Windows, x86 registry is in Wow6432Node if IsWin64 then begin if RegQueryDWordValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Installed', Installed) then begin Result := (Installed = 1); end; if not Result then begin if RegQueryDWordValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\X86', 'Installed', Installed) then begin Result := (Installed = 1); end; end; end else begin // On 32-bit Windows if RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Installed', Installed) then begin Result := (Installed = 1); end; end; end; // Check if .NET Framework 4.8 or later is installed function IsDotNet48Installed: Boolean; var Release: Cardinal; begin Result := False; // .NET Framework 4.8 has release key >= 528040 // 528040 = Windows 10 May 2019 Update // 528049 = All other Windows versions if RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', Release) then begin Result := (Release >= 528040); end; end; // ============================================ // Check Prerequisites (called early for silent mode) // ============================================ procedure CheckPrerequisites; begin VCx86Needed := not IsVCx86Installed; VCx64Needed := not IsVCx64Installed; DotNetNeeded := not IsDotNet48Installed; RebootRequired := False; end; // ============================================ // Wizard Page Setup // ============================================ procedure InitializeWizard(); begin // Create progress page for prerequisite installation ProgressPage := CreateOutputProgressPage('Installing Prerequisites', 'Please wait while the required components are being installed...'); // Create prerequisites summary page (only shown in non-silent mode) PrereqPage := CreateOutputMsgMemoPage(wpWelcome, 'Prerequisites Check', 'The installer has checked for required components.', 'Status of required prerequisites:', ''); end; // ============================================ // Prerequisites Check on Welcome Page // ============================================ function NextButtonClick(CurPageID: Integer): Boolean; begin Result := True; if CurPageID = wpWelcome then begin // Check all prerequisites CheckPrerequisites; // Build summary text PrereqSummary := ''; PrereqSummary := PrereqSummary + 'Visual C++ Redistributable (x86): '; if VCx86Needed then PrereqSummary := PrereqSummary + 'NOT INSTALLED - Will be installed'#13#10 else PrereqSummary := PrereqSummary + 'Already installed'#13#10; PrereqSummary := PrereqSummary + #13#10'Visual C++ Redistributable (x64): '; if VCx64Needed then PrereqSummary := PrereqSummary + 'NOT INSTALLED - Will be installed'#13#10 else PrereqSummary := PrereqSummary + 'Already installed'#13#10; PrereqSummary := PrereqSummary + #13#10'.NET Framework 4.8: '; if DotNetNeeded then PrereqSummary := PrereqSummary + 'NOT INSTALLED - Will be installed'#13#10 else PrereqSummary := PrereqSummary + 'Already installed'#13#10; PrereqSummary := PrereqSummary + #13#10'-------------------------------------------'#13#10; if VCx86Needed or VCx64Needed or DotNetNeeded then PrereqSummary := PrereqSummary + #13#10'Missing prerequisites will be installed before JT2Go.'#13#10 + 'This may require a system restart if .NET Framework 4.8 is installed.' else PrereqSummary := PrereqSummary + #13#10'All prerequisites are already installed.'#13#10 + 'JT2Go installation will proceed directly.'; // Update the prereq page memo PrereqPage.RichEditViewer.RTFText := PrereqSummary; end; end; // ============================================ // Install Prerequisites Function // ============================================ function InstallPrerequisites: Boolean; var ResultCode: Integer; ErrorMsg: String; begin Result := True; if not WizardSilent then ProgressPage.Show; try // ============================================ // Install VC++ x86 if needed // ============================================ if VCx86Needed then begin if not WizardSilent then begin ProgressPage.SetText('Installing Visual C++ Redistributable (x86)...', 'This may take a few moments...'); ProgressPage.SetProgress(1, 4); end; // Run VC_redist.x86.exe with silent install // /install /quiet /norestart if not Exec(ExpandConstant('{tmp}\VC_redist.x86.exe'), '/install /quiet /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then begin ErrorMsg := 'Failed to launch VC++ x86 installer.'; ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; // Check result code (0 = success, 3010 = success but reboot needed) if (ResultCode <> 0) and (ResultCode <> 3010) then begin ErrorMsg := 'VC++ x86 installation failed with error code: ' + IntToStr(ResultCode); ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; if ResultCode = 3010 then RebootRequired := True; end; // ============================================ // Install VC++ x64 if needed // ============================================ if VCx64Needed then begin if not WizardSilent then begin ProgressPage.SetText('Installing Visual C++ Redistributable (x64)...', 'This may take a few moments...'); ProgressPage.SetProgress(2, 4); end; if not Exec(ExpandConstant('{tmp}\VC_redist.x64.exe'), '/install /quiet /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then begin ErrorMsg := 'Failed to launch VC++ x64 installer.'; ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; if (ResultCode <> 0) and (ResultCode <> 3010) then begin ErrorMsg := 'VC++ x64 installation failed with error code: ' + IntToStr(ResultCode); ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; if ResultCode = 3010 then RebootRequired := True; end; // ============================================ // Install .NET Framework 4.8 if needed // ============================================ if DotNetNeeded then begin if not WizardSilent then begin ProgressPage.SetText('Installing .NET Framework 4.8...', 'This may take several minutes. Please wait...'); ProgressPage.SetProgress(3, 4); end; // Run .NET installer with silent install // /q /norestart if not Exec(ExpandConstant('{tmp}\NDP48-x86-x64-AllOS-ENU.exe'), '/q /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then begin ErrorMsg := 'Failed to launch .NET Framework 4.8 installer.'; ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; // Check result codes // 0 = success // 3010 = success, reboot required // 1641 = success, reboot initiated // 1602 = user cancelled // 1603 = fatal error // 5100 = computer does not meet requirements case ResultCode of 0: begin // Success, no reboot needed end; 3010, 1641: begin // Success but reboot required RebootRequired := True; end; 1602: begin ErrorMsg := '.NET Framework installation was cancelled.'; ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; 5100: begin ErrorMsg := 'This computer does not meet the requirements for .NET Framework 4.8.'; ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; else begin ErrorMsg := '.NET Framework 4.8 installation failed with error code: ' + IntToStr(ResultCode); ShowMessage(ErrorMsg, mbError); Result := False; Exit; end; end; end; if not WizardSilent then ProgressPage.SetProgress(4, 4); finally if not WizardSilent then ProgressPage.Hide; end; end; // ============================================ // Main Installation Step // ============================================ procedure CurStepChanged(CurStep: TSetupStep); var ResultCode: Integer; JT2GoExe: String; JT2GoParams: String; WorkDir: String; ShowWindow: Integer; begin if CurStep = ssPostInstall then begin // For silent mode, check prerequisites here since wizard pages are skipped if WizardSilent then CheckPrerequisites; // First, install prerequisites if needed if VCx86Needed or VCx64Needed or DotNetNeeded then begin if not InstallPrerequisites then begin // Prerequisite installation failed Exit; end; end; // Check if reboot is required before continuing if RebootRequired then begin ShowMessage('.NET Framework 4.8 was installed successfully.' + #13#10 + 'A system restart is required to complete the installation.' + #13#10#13#10 + 'Please restart your computer and run this installer again to complete JT2Go installation.', mbInformation); Exit; end; // Now run the JT2Go installer if not WizardSilent then begin ProgressPage.SetText('Installing JT2Go 2512...', 'The JT2Go installer will now launch. Please follow its prompts.'); ProgressPage.SetProgress(1, 1); ProgressPage.Show; end; try JT2GoExe := ExpandConstant('{tmp}\JT2GoSetup.exe'); WorkDir := ExpandConstant('{tmp}'); // Determine parameters based on silent mode if WizardSilent then begin // Silent installation of JT2Go // /S = silent for exe wrapper, /qn = quiet no UI for MSI JT2GoParams := '/L1033 /S /v"/qn /norestart"'; ShowWindow := SW_HIDE; end else begin // Interactive installation - just set language to English JT2GoParams := '/L1033'; ShowWindow := SW_SHOW; end; // Execute JT2Go installer directly (not via batch file for better control) if not Exec(JT2GoExe, JT2GoParams, WorkDir, ShowWindow, ewWaitUntilTerminated, ResultCode) then begin ShowMessage('Failed to launch JT2Go installer.' + #13#10 + 'Please run JT2GoSetup.exe manually from the installation files.', mbError); Exit; end; // Check result if ResultCode <> 0 then begin // Non-zero doesn't always mean failure for installers // 0 = success, 3010 = success with reboot required if ResultCode = 3010 then begin ShowMessage('Installation Complete!' + #13#10#13#10 + 'JT2Go 2512 has been installed successfully.' + #13#10 + 'A system restart may be required.', mbInformation); end else begin ShowMessage('JT2Go installation completed with exit code: ' + IntToStr(ResultCode) + #13#10#13#10 + 'Please verify JT2Go is installed correctly.', mbInformation); end; end else begin ShowMessage('Installation Complete!' + #13#10#13#10 + 'JT2Go 2512 has been installed successfully.' + #13#10#13#10 + 'All prerequisites were verified/installed:' + #13#10 + ' - Visual C++ Redistributable (x86)' + #13#10 + ' - Visual C++ Redistributable (x64)' + #13#10 + ' - .NET Framework 4.8', mbInformation); end; finally if not WizardSilent then ProgressPage.Hide; end; end; end; // ============================================ // Initialization - Admin Check // ============================================ function InitializeSetup(): Boolean; begin Result := True; RebootRequired := False; // Additional admin check at runtime // Note: PrivilegesRequired=admin already enforces this, but this provides a clearer message if not IsAdmin then begin ShowMessage('Administrator Privileges Required' + #13#10#13#10 + 'This installer must be run with administrative privileges.' + #13#10#13#10 + 'Please right-click the installer and select "Run as administrator".', mbError); Result := False; Exit; end; end; // ============================================ // Return proper exit code for reboot scenarios // ============================================ function NeedRestart(): Boolean; begin Result := RebootRequired; end;