Add JT2GO, NetworkDriveManager, and Template projects
JT2GO: - Inno Setup installer for JT2Go with prerequisite checking - Checks for VC++ x86/x64 redistributables and .NET 4.8 - Verifies admin privileges before installation - Supports silent installation mode NetworkDriveManager: - Full Inno Setup implementation with integrated PowerShell logic - Menu-based interface for managing legacy domain network drives - Features: backup/restore mappings, credential testing, drive reset - Server migration from rd.ds.ge.com to wjs.geaerospace.net - Three-phase reconnection to prevent error 1219 with multiple shares - Add predefined drives (S:, V:, Y:) functionality Template: - Reusable Inno Setup project template for co-workers - Documented sections with examples and best practices - Includes utility functions and common patterns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
504
JT2GO/JT2GO.iss
Normal file
504
JT2GO/JT2GO.iss
Normal file
@@ -0,0 +1,504 @@
|
||||
; 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;
|
||||
Reference in New Issue
Block a user