Initial commit: Inno Setup installer packages

Installer packages for GE manufacturing tools:
- BlueSSOFix: Blue SSO authentication fix
- HIDCardPrinter: HID card printer setup
- HPOfflineInstaller: HP printer offline installer
- MappedDrive: Network drive mapping
- PrinterInstaller: General printer installer
- ShopfloorConnect: Shopfloor connectivity tool
- XeroxOfflineInstaller: Xerox printer offline installer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2025-12-30 13:15:54 -05:00
commit 28541cd3ed
1175 changed files with 127441 additions and 0 deletions

View File

@@ -0,0 +1,797 @@
; Universal Printer Installer for Network Printers
; Installs HP/Xerox network printers from ShopDB via TCP/IP
[Setup]
AppId={{7B9C3E41-5F2A-4D8B-9E1C-8A6D4F3E2B1A}}
AppName=WJDT GE Aerospace Printer Installer
AppVersion=1.0
AppPublisher=WJDT
AppPublisherURL=http://tsgwp00524.logon.ds.ge.com
AppSupportURL=http://tsgwp00524.logon.ds.ge.com
AppUpdatesURL=http://tsgwp00524.logon.ds.ge.com
CreateAppDir=no
ChangesAssociations=no
PrivilegesRequired=admin
; Force 64-bit installation mode on 64-bit compatible systems
ArchitecturesInstallIn64BitMode=x64compatible
OutputDir=C:\Users\570005354\Downloads\Output
OutputBaseFilename=PrinterInstaller
SolidCompression=yes
WizardStyle=modern
SetupIconFile=gea-logo.ico
WizardImageFile=patrick.bmp
WizardSmallImageFile=patrick-sm.bmp
CreateUninstallRegKey=no
DisableWelcomePage=no
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Messages]
WelcomeLabel2=This utility will install network printers.%n%nFeatures:%n- Query HP/Xerox printers from ShopDB%n- Install via TCP/IP using FQDN or IP address%n- Automatic driver installation (HP Universal PCL6, Xerox Global Print Driver)%n%nClick Next to continue.
[Files]
; HP Universal Print Driver x64
Source: "drivers\hp_x64\*"; DestDir: "{tmp}\hp_drivers_x64"; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode
; HP Universal Print Driver x32
Source: "drivers\hp_x32\*"; DestDir: "{tmp}\hp_drivers_x32"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode
; Xerox Universal Print Driver x64
Source: "drivers\xerox_x64\*"; DestDir: "{tmp}\xerox_drivers_x64"; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode
; Xerox Universal Print Driver x32
Source: "drivers\xerox_x32\*"; DestDir: "{tmp}\xerox_drivers_x32"; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode
[Code]
var
PrinterSelectionPage: TInputOptionWizardPage;
PrinterDataArray: array of record
PrinterName: String;
FQDN: String;
IPAddress: String;
Vendor: String;
Model: String;
IsInstalled: Boolean;
end;
// Query database for printers via web API
function QueryPrinters(): Boolean;
var
ResultCode: Integer;
TempScriptPath, TempOutputPath: String;
PSScript: String;
Output: AnsiString;
Lines: TStringList;
I: Integer;
Fields: TStringList;
begin
Result := False;
// Build PowerShell script to query database API
PSScript :=
'try {' + #13#10 +
' $url = "https://tsgwp00525.rd.ds.ge.com/shopdb/api_printers.asp"' + #13#10 +
' # Allow TLS 1.2 for HTTPS connections' + #13#10 +
' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12' + #13#10 +
' $response = Invoke-WebRequest -Uri $url -Method GET -UseBasicParsing -UseDefaultCredentials -ErrorAction Stop' + #13#10 +
' $printers = $response.Content | ConvertFrom-Json' + #13#10 +
' foreach ($printer in $printers) {' + #13#10 +
' if (($printer.isactive -eq 1 -or $printer.isactive -eq $true) -and ($printer.vendor -eq "HP" -or $printer.vendor -eq "Xerox" -or $printer.vendor -eq "HID")) {' + #13#10 +
' $name = $printer.printerwindowsname' + #13#10 +
' $vendor = $printer.vendor' + #13#10 +
' $model = $printer.modelnumber' + #13#10 +
' # Use FQDN or IP if available, otherwise default to USB for card printers' + #13#10 +
' if ($printer.fqdn -and $printer.fqdn -ne "" -and $printer.fqdn -ne "USB") {' + #13#10 +
' $address = $printer.fqdn' + #13#10 +
' } elseif ($printer.ipaddress -and $printer.ipaddress -ne "") {' + #13#10 +
' $address = $printer.ipaddress' + #13#10 +
' } else {' + #13#10 +
' $address = "USB"' + #13#10 +
' }' + #13#10 +
' if ($address -and $address -ne "") {' + #13#10 +
' Write-Output "$name|$address|$vendor|$model"' + #13#10 +
' }' + #13#10 +
' }' + #13#10 +
' }' + #13#10 +
'} catch {' + #13#10 +
' Write-Error "Failed to query printers: $_"' + #13#10 +
' exit 1' + #13#10 +
'}';
TempScriptPath := ExpandConstant('{tmp}\query_printers.ps1');
TempOutputPath := ExpandConstant('{tmp}\printers_output.txt');
SaveStringToFile(TempScriptPath, PSScript, False);
if not Exec('powershell.exe',
'-NoProfile -ExecutionPolicy Bypass -Command "& ''' + TempScriptPath + ''' | Out-File -FilePath ''' + TempOutputPath + ''' -Encoding ASCII"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
DeleteFile(TempScriptPath);
Exit;
end;
DeleteFile(TempScriptPath);
if not FileExists(TempOutputPath) then
Exit;
if not LoadStringFromFile(TempOutputPath, Output) then
begin
DeleteFile(TempOutputPath);
Exit;
end;
DeleteFile(TempOutputPath);
Lines := TStringList.Create;
try
Lines.Text := Output;
// Count valid lines
I := 0;
while I < Lines.Count do
begin
if (Trim(Lines[I]) = '') or (Pos('|', Lines[I]) = 0) then
Lines.Delete(I)
else
I := I + 1;
end;
if Lines.Count = 0 then
Exit;
SetArrayLength(PrinterDataArray, Lines.Count);
for I := 0 to Lines.Count - 1 do
begin
Fields := TStringList.Create;
try
Fields.Delimiter := '|';
Fields.StrictDelimiter := True;
Fields.DelimitedText := Trim(Lines[I]);
if Fields.Count >= 4 then
begin
PrinterDataArray[I].PrinterName := Trim(Fields[0]);
PrinterDataArray[I].FQDN := Trim(Fields[1]);
PrinterDataArray[I].IPAddress := Trim(Fields[1]);
PrinterDataArray[I].Vendor := Trim(Fields[2]);
PrinterDataArray[I].Model := Trim(Fields[3]);
Result := True;
end;
finally
Fields.Free;
end;
end;
finally
Lines.Free;
end;
end;
// Check which printers are already installed
function CheckInstalledPrinters(): Boolean;
var
ResultCode: Integer;
TempScriptPath, TempOutputPath: String;
PSScript: String;
Output: AnsiString;
Lines: TStringList;
I, J: Integer;
begin
Result := False;
// Build PowerShell script to get installed printers
PSScript :=
'try {' + #13#10 +
' Get-Printer | Select-Object -ExpandProperty Name | ForEach-Object { Write-Output $_ }' + #13#10 +
'} catch { exit 1 }';
TempScriptPath := ExpandConstant('{tmp}\check_installed.ps1');
TempOutputPath := ExpandConstant('{tmp}\installed_output.txt');
SaveStringToFile(TempScriptPath, PSScript, False);
if not Exec('powershell.exe',
'-NoProfile -ExecutionPolicy Bypass -Command "& ''' + TempScriptPath + ''' | Out-File -FilePath ''' + TempOutputPath + ''' -Encoding ASCII"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
DeleteFile(TempScriptPath);
Exit;
end;
DeleteFile(TempScriptPath);
if not FileExists(TempOutputPath) then
Exit;
if not LoadStringFromFile(TempOutputPath, Output) then
begin
DeleteFile(TempOutputPath);
Exit;
end;
DeleteFile(TempOutputPath);
Lines := TStringList.Create;
try
Lines.Text := Output;
// Check each printer in database against installed printers
for I := 0 to GetArrayLength(PrinterDataArray) - 1 do
begin
PrinterDataArray[I].IsInstalled := False;
for J := 0 to Lines.Count - 1 do
begin
if Trim(Lines[J]) = PrinterDataArray[I].PrinterName then
begin
PrinterDataArray[I].IsInstalled := True;
Break;
end;
end;
end;
Result := True;
finally
Lines.Free;
end;
end;
// Initialize wizard pages
procedure InitializeWizard();
var
I: Integer;
DisplayText: String;
AutoSelectPrinter: String;
FoundMatch: Boolean;
begin
// Query printers from database
if not QueryPrinters() then
begin
MsgBox('Failed to query printers from ShopDB database.' + #13#10#13#10 +
'Please ensure:' + #13#10 +
'- You have network connectivity' + #13#10 +
'- The ShopDB server (tsgwp00525.rd.ds.ge.com) is accessible' + #13#10 +
'- You are connected to the GE network' + #13#10 +
'- The API endpoint is running',
mbError, MB_OK);
WizardForm.Close;
Exit;
end;
if GetArrayLength(PrinterDataArray) = 0 then
begin
MsgBox('No printers found in the database.' + #13#10#13#10 +
'This installer supports:' + #13#10 +
'- HP and Xerox network printers (TCP/IP)' + #13#10 +
'- HID card printers (USB)',
mbInformation, MB_OK);
WizardForm.Close;
Exit;
end;
// Check which printers are already installed
CheckInstalledPrinters();
// Check for command-line parameter to auto-select printer(s)
// Usage: PrinterInstaller.exe /PRINTER="PrinterName"
// Or multiple: /PRINTER="Printer1,Printer2,Printer3"
AutoSelectPrinter := ExpandConstant('{param:PRINTER|}');
FoundMatch := False;
// Create printer selection page
PrinterSelectionPage := CreateInputOptionPage(wpWelcome,
'Manage Network Printers',
'Select printers to install or uncheck to remove',
'Checked printers will be installed. Unchecked printers that are currently installed will be removed. ' +
'Already-installed printers are pre-checked.',
False,
False);
// Add printers to selection page
for I := 0 to GetArrayLength(PrinterDataArray) - 1 do
begin
if PrinterDataArray[I].PrinterName <> '' then
begin
if PrinterDataArray[I].IsInstalled then
DisplayText := '[INSTALLED] '
else
DisplayText := '';
DisplayText := DisplayText + PrinterDataArray[I].PrinterName + ' - ' +
PrinterDataArray[I].Vendor + ' ' +
PrinterDataArray[I].Model + ' (' +
PrinterDataArray[I].FQDN + ')';
PrinterSelectionPage.Add(DisplayText);
// Check if this printer should be auto-selected via command line
if AutoSelectPrinter <> '' then
begin
// First try exact match against each comma-separated printer name
if Pos(',', AutoSelectPrinter) > 0 then
begin
// Multiple printers separated by comma - check for exact matches
if Pos(',' + PrinterDataArray[I].PrinterName + ',', ',' + AutoSelectPrinter + ',') > 0 then
begin
PrinterSelectionPage.Values[I] := True;
FoundMatch := True;
end
else if PrinterDataArray[I].IsInstalled then
PrinterSelectionPage.Values[I] := True
else
PrinterSelectionPage.Values[I] := False;
end
else
begin
// Single printer - use partial match (original behavior)
if Pos(AutoSelectPrinter, PrinterDataArray[I].PrinterName) > 0 then
begin
PrinterSelectionPage.Values[I] := True;
FoundMatch := True;
end
else if PrinterDataArray[I].IsInstalled then
PrinterSelectionPage.Values[I] := True
else
PrinterSelectionPage.Values[I] := False;
end;
end
// No auto-select parameter - pre-check if already installed
else if PrinterDataArray[I].IsInstalled then
begin
PrinterSelectionPage.Values[I] := True;
end
else
begin
PrinterSelectionPage.Values[I] := False;
end;
end;
end;
// If command-line parameter was provided but no match found, show warning
if (AutoSelectPrinter <> '') and (not FoundMatch) then
begin
MsgBox('Printer "' + AutoSelectPrinter + '" not found in the database.' + #13#10#13#10 +
'Please select a printer from the list manually.',
mbInformation, MB_OK);
end;
end;
// Validate selection before continuing
function NextButtonClick(CurPageID: Integer): Boolean;
var
I: Integer;
HasChange: Boolean;
begin
Result := True;
if CurPageID = PrinterSelectionPage.ID then
begin
HasChange := False;
// Check if any printer state has changed
for I := 0 to GetArrayLength(PrinterDataArray) - 1 do
begin
// If checkbox state differs from installation state, we have a change
if PrinterSelectionPage.Values[I] <> PrinterDataArray[I].IsInstalled then
begin
HasChange := True;
Break;
end;
end;
if not HasChange then
begin
MsgBox('No changes detected. Select printers to install or uncheck installed printers to remove them.',
mbInformation, MB_OK);
Result := False;
end;
end;
end;
// Install printers during installation phase (after files are extracted)
procedure CurStepChanged(CurStep: TSetupStep);
var
I: Integer;
PSScript: String;
TempScriptPath: String;
ResultCode: Integer;
TotalCount: Integer;
IsX64: Boolean;
HPDriverPath, XeroxDriverPath: String;
begin
// Run after files are extracted but before finishing
if CurStep = ssPostInstall then
begin
// Check if there are any changes to process (installs or removals)
TotalCount := 0;
for I := 0 to GetArrayLength(PrinterDataArray) - 1 do
begin
// Count changes: either installing (not installed but checked) or removing (installed but unchecked)
if (not PrinterDataArray[I].IsInstalled and PrinterSelectionPage.Values[I]) or
(PrinterDataArray[I].IsInstalled and not PrinterSelectionPage.Values[I]) then
TotalCount := TotalCount + 1;
end;
if TotalCount = 0 then
Exit;
// Determine architecture and driver paths
IsX64 := Is64BitInstallMode;
if IsX64 then
begin
HPDriverPath := ExpandConstant('{tmp}\hp_drivers_x64');
XeroxDriverPath := ExpandConstant('{tmp}\xerox_drivers_x64\UNIV_5.1055.3.0_PCL6_x64_Driver.inf\x3UNIVX.inf');
end
else
begin
HPDriverPath := ExpandConstant('{tmp}\hp_drivers_x32');
XeroxDriverPath := ExpandConstant('{tmp}\xerox_drivers_x32');
end;
// Build PowerShell installation script
PSScript :=
'$ErrorActionPreference = "Continue"' + #13#10 +
'# Installer architecture mode (matches file copy behavior)' + #13#10;
if IsX64 then
PSScript := PSScript + '$Is64BitInstallMode = $true' + #13#10
else
PSScript := PSScript + '$Is64BitInstallMode = $false' + #13#10;
PSScript := PSScript +
'Write-Host ""' + #13#10 +
'Write-Host "========================================" -ForegroundColor Cyan' + #13#10 +
'Write-Host " WJDT Printer Installer" -ForegroundColor Cyan' + #13#10 +
'Write-Host "========================================" -ForegroundColor Cyan' + #13#10 +
'Write-Host ""' + #13#10 +
'' + #13#10 +
'# Function to install printer driver' + #13#10 +
'function Install-PrinterDriver {' + #13#10 +
' param(' + #13#10 +
' [string]$Vendor,' + #13#10 +
' [string]$DriverPath' + #13#10 +
' )' + #13#10 +
'' + #13#10 +
' try {' + #13#10 +
' if ($Vendor -eq "HP") {' + #13#10 +
' $driverName = "HP Universal Printing PCL 6"' + #13#10 +
' # Use different INF file for x32 vs x64' + #13#10 +
' if ($DriverPath -like "*x64*") {' + #13#10 +
' $infFile = Join-Path $DriverPath "hpcu345u.inf"' + #13#10 +
' } else {' + #13#10 +
' $infFile = Join-Path $DriverPath "hpcu345c.inf"' + #13#10 +
' }' + #13#10 +
' } elseif ($Vendor -eq "Xerox") {' + #13#10 +
' $driverName = "Xerox Global Print Driver PCL6"' + #13#10 +
' # Check if DriverPath is already an INF file (x64) or directory (x32)' + #13#10 +
' if ($DriverPath -like "*.inf") {' + #13#10 +
' $infFile = $DriverPath' + #13#10 +
' } else {' + #13#10 +
' $infFile = Join-Path $DriverPath "x3UNIVX.inf"' + #13#10 +
' }' + #13#10 +
' } else {' + #13#10 +
' return $false' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Check if driver already installed' + #13#10 +
' $existingDriver = Get-PrinterDriver -Name $driverName -ErrorAction SilentlyContinue' + #13#10 +
' if ($existingDriver) {' + #13#10 +
' Write-Host " $driverName already installed" -ForegroundColor Gray' + #13#10 +
' return $true' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' Write-Host " Installing $driverName driver..." -ForegroundColor Yellow' + #13#10 +
'' + #13#10 +
' # Locate pnputil.exe - check all possible locations' + #13#10 +
' $pnputil = $null' + #13#10 +
' $pnputilLocations = @(' + #13#10 +
' (Join-Path $env:SystemRoot "System32\pnputil.exe"),' + #13#10 +
' (Join-Path $env:SystemRoot "SysNative\pnputil.exe"),' + #13#10 +
' (Join-Path $env:SystemRoot "Syswow64\pnputil.exe"),' + #13#10 +
' "C:\Windows\System32\pnputil.exe",' + #13#10 +
' "C:\Windows\SysNative\pnputil.exe",' + #13#10 +
' "C:\Windows\Syswow64\pnputil.exe"' + #13#10 +
' )' + #13#10 +
'' + #13#10 +
' foreach ($location in $pnputilLocations) {' + #13#10 +
' if (Test-Path $location) {' + #13#10 +
' $pnputil = $location' + #13#10 +
' Write-Host " Found pnputil at: $pnputil" -ForegroundColor Gray' + #13#10 +
' break' + #13#10 +
' }' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Try PATH as last resort' + #13#10 +
' if (-not $pnputil) {' + #13#10 +
' $pnputil = (Get-Command pnputil.exe -ErrorAction SilentlyContinue).Path' + #13#10 +
' if ($pnputil) {' + #13#10 +
' Write-Host " Found pnputil in PATH: $pnputil" -ForegroundColor Gray' + #13#10 +
' }' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # If still not found, try without full path' + #13#10 +
' if (-not $pnputil) {' + #13#10 +
' $pnputil = "pnputil.exe"' + #13#10 +
' Write-Host " Using pnputil.exe from system PATH (no full path)" -ForegroundColor Gray' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Use pnputil to add driver package' + #13#10 +
' try {' + #13#10 +
' # Debug: Verify file exists' + #13#10 +
' Write-Host " INF file path: $infFile" -ForegroundColor Gray' + #13#10 +
' if (Test-Path $infFile) {' + #13#10 +
' Write-Host " INF file exists: YES" -ForegroundColor Green' + #13#10 +
' } else {' + #13#10 +
' Write-Host " INF file exists: NO - FILE NOT FOUND!" -ForegroundColor Red' + #13#10 +
' Write-Host " ERROR: Cannot proceed without INF file" -ForegroundColor Red' + #13#10 +
' return $false' + #13#10 +
' }' + #13#10 +
' Write-Host " Running: & $pnputil /add-driver $infFile /install" -ForegroundColor Gray' + #13#10 +
' $pnpResult = & $pnputil /add-driver "$infFile" /install 2>&1' + #13#10 +
' $pnpExitCode = $LASTEXITCODE' + #13#10 +
' Write-Host " pnputil exit code: $pnpExitCode" -ForegroundColor Gray' + #13#10 +
' if ($pnpResult) {' + #13#10 +
' Write-Host " pnputil output: $pnpResult" -ForegroundColor Gray' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Exit code 0 = success, 259 = driver already installed' + #13#10 +
' if ($pnpExitCode -ne 0 -and $pnpExitCode -ne 259) {' + #13#10 +
' Write-Host " Warning: pnputil returned code $pnpExitCode" -ForegroundColor Yellow' + #13#10 +
' }' + #13#10 +
' } catch {' + #13#10 +
' Write-Host " Warning: pnputil execution failed: $_" -ForegroundColor Yellow' + #13#10 +
' Write-Host " Attempting to continue with Add-PrinterDriver..." -ForegroundColor Yellow' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' Start-Sleep -Seconds 5' + #13#10 +
'' + #13#10 +
' # Try to add printer driver using PowerShell cmdlet' + #13#10 +
' try {' + #13#10 +
' Add-PrinterDriver -Name $driverName -ErrorAction Stop' + #13#10 +
' Write-Host " $driverName installed successfully" -ForegroundColor Green' + #13#10 +
' return $true' + #13#10 +
' } catch {' + #13#10 +
' # If Add-PrinterDriver fails, try legacy rundll32 method' + #13#10 +
' Write-Host " Add-PrinterDriver failed, trying legacy method..." -ForegroundColor Yellow' + #13#10 +
' try {' + #13#10 +
' $null = rundll32 printui.dll,PrintUIEntry /ia /m "$driverName" /f "$infFile"' + #13#10 +
' Start-Sleep -Seconds 3' + #13#10 +
' # Verify driver was installed' + #13#10 +
' $verifyDriver = Get-PrinterDriver -Name $driverName -ErrorAction SilentlyContinue' + #13#10 +
' if ($verifyDriver) {' + #13#10 +
' Write-Host " $driverName installed via legacy method" -ForegroundColor Green' + #13#10 +
' return $true' + #13#10 +
' } else {' + #13#10 +
' Write-Host " Warning: Driver installation could not be verified" -ForegroundColor Yellow' + #13#10 +
' return $true # Continue anyway' + #13#10 +
' }' + #13#10 +
' } catch {' + #13#10 +
' Write-Host " Warning: Legacy installation also failed" -ForegroundColor Yellow' + #13#10 +
' return $true # Continue anyway, printer creation might still work' + #13#10 +
' }' + #13#10 +
' }' + #13#10 +
' } catch {' + #13#10 +
' Write-Host " Error installing driver: $_" -ForegroundColor Red' + #13#10 +
' return $false' + #13#10 +
' }' + #13#10 +
'}' + #13#10 +
'' + #13#10 +
'# Function to remove printer and its port' + #13#10 +
'function Remove-NetworkPrinter {' + #13#10 +
' param(' + #13#10 +
' [string]$PrinterName,' + #13#10 +
' [string]$PortAddress' + #13#10 +
' )' + #13#10 +
'' + #13#10 +
' try {' + #13#10 +
' Write-Host ""' + #13#10 +
' Write-Host "Removing: $PrinterName" -ForegroundColor Magenta' + #13#10 +
'' + #13#10 +
' # Check if printer exists' + #13#10 +
' $existingPrinter = Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue' + #13#10 +
' if (-not $existingPrinter) {' + #13#10 +
' Write-Host " SKIPPED: Printer not found" -ForegroundColor Yellow' + #13#10 +
' return $true' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Remove printer' + #13#10 +
' Write-Host " Removing printer..." -ForegroundColor Yellow' + #13#10 +
' Remove-Printer -Name $PrinterName -ErrorAction Stop' + #13#10 +
' Write-Host " Printer removed" -ForegroundColor Green' + #13#10 +
'' + #13#10 +
' # Remove port if exists and not used by other printers' + #13#10 +
' $portName = "IP_$PortAddress"' + #13#10 +
' $existingPort = Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue' + #13#10 +
' if ($existingPort) {' + #13#10 +
' $printersUsingPort = Get-Printer | Where-Object { $_.PortName -eq $portName }' + #13#10 +
' if ($printersUsingPort.Count -eq 0) {' + #13#10 +
' Write-Host " Removing unused port..." -ForegroundColor Yellow' + #13#10 +
' Remove-PrinterPort -Name $portName -ErrorAction Stop' + #13#10 +
' Write-Host " Port removed: $portName" -ForegroundColor Green' + #13#10 +
' } else {' + #13#10 +
' Write-Host " Port still in use by other printers" -ForegroundColor Gray' + #13#10 +
' }' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' Write-Host " SUCCESS: $PrinterName removed" -ForegroundColor Green' + #13#10 +
' return $true' + #13#10 +
' } catch {' + #13#10 +
' Write-Host " ERROR: $_" -ForegroundColor Red' + #13#10 +
' return $false' + #13#10 +
' }' + #13#10 +
'}' + #13#10 +
'' + #13#10 +
'# Function to install individual printer' + #13#10 +
'function Install-NetworkPrinter {' + #13#10 +
' param(' + #13#10 +
' [string]$PrinterName,' + #13#10 +
' [string]$PortAddress,' + #13#10 +
' [string]$Vendor,' + #13#10 +
' [string]$Model' + #13#10 +
' )' + #13#10 +
'' + #13#10 +
' try {' + #13#10 +
' Write-Host ""' + #13#10 +
' Write-Host "Installing: $PrinterName" -ForegroundColor Cyan' + #13#10 +
' Write-Host " Address: $PortAddress" -ForegroundColor Gray' + #13#10 +
' Write-Host " Model: $Vendor $Model" -ForegroundColor Gray' + #13#10 +
'' + #13#10 +
' # Determine driver name' + #13#10 +
' if ($Vendor -eq "HP") {' + #13#10 +
' $driverName = "HP Universal Printing PCL 6"' + #13#10 +
' } elseif ($Vendor -eq "Xerox") {' + #13#10 +
' $driverName = "Xerox Global Print Driver PCL6"' + #13#10 +
' } elseif ($Vendor -eq "HID") {' + #13#10 +
' $driverName = "DTC4500e Card Printer"' + #13#10 +
' } else {' + #13#10 +
' Write-Host " Unknown vendor: $Vendor" -ForegroundColor Red' + #13#10 +
' return $false' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # For USB card printers, driver installation is enough' + #13#10 +
' # User plugs in USB device and Windows auto-configures it' + #13#10 +
' if ($PortAddress -eq "USB") {' + #13#10 +
' Write-Host " USB card printer - driver installed" -ForegroundColor Green' + #13#10 +
' Write-Host " Connect printer via USB and Windows will detect it" -ForegroundColor Gray' + #13#10 +
' Write-Host " SUCCESS: $driverName ready for USB device" -ForegroundColor Green' + #13#10 +
' return $true' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # For network printers, check if printer already exists' + #13#10 +
' $existingPrinter = Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue' + #13#10 +
' if ($existingPrinter) {' + #13#10 +
' Write-Host " SKIPPED: Printer already exists" -ForegroundColor Yellow' + #13#10 +
' return $true' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Create port name for network printers' + #13#10 +
' $portName = "IP_$PortAddress"' + #13#10 +
'' + #13#10 +
' # Check if port exists' + #13#10 +
' $existingPort = Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue' + #13#10 +
' if (-not $existingPort) {' + #13#10 +
' Write-Host " Creating printer port..." -ForegroundColor Yellow' + #13#10 +
' Add-PrinterPort -Name $portName -PrinterHostAddress $PortAddress -ErrorAction Stop' + #13#10 +
' Write-Host " Port created: $portName" -ForegroundColor Green' + #13#10 +
' } else {' + #13#10 +
' Write-Host " Using existing port: $portName" -ForegroundColor Gray' + #13#10 +
' }' + #13#10 +
'' + #13#10 +
' # Add printer' + #13#10 +
' Write-Host " Adding printer..." -ForegroundColor Yellow' + #13#10 +
' Add-Printer -Name $PrinterName -DriverName $driverName -PortName $portName -ErrorAction Stop' + #13#10 +
' Write-Host " SUCCESS: $PrinterName installed" -ForegroundColor Green' + #13#10 +
' return $true' + #13#10 +
' } catch {' + #13#10 +
' Write-Host " ERROR: $_" -ForegroundColor Red' + #13#10 +
' return $false' + #13#10 +
' }' + #13#10 +
'}' + #13#10 +
'' + #13#10 +
'Write-Host "Step 1: Installing printer drivers..." -ForegroundColor Cyan' + #13#10 +
'Write-Host ""' + #13#10 +
'' + #13#10;
// Install HP driver if needed
PSScript := PSScript +
'if (Install-PrinterDriver -Vendor "HP" -DriverPath "' + HPDriverPath + '") {' + #13#10 +
' Write-Host ""' + #13#10 +
'} else {' + #13#10 +
' Write-Host "Failed to install HP driver. Continuing anyway..." -ForegroundColor Yellow' + #13#10 +
' Write-Host ""' + #13#10 +
'}' + #13#10;
// Install Xerox driver (both x64 and x32 now supported)
PSScript := PSScript +
'if (Install-PrinterDriver -Vendor "Xerox" -DriverPath "' + XeroxDriverPath + '") {' + #13#10 +
' Write-Host ""' + #13#10 +
'} else {' + #13#10 +
' Write-Host "Failed to install Xerox driver. Continuing anyway..." -ForegroundColor Yellow' + #13#10 +
' Write-Host ""' + #13#10 +
'}' + #13#10 +
'' + #13#10;
PSScript := PSScript +
'Write-Host "Step 2: Processing printer changes..." -ForegroundColor Cyan' + #13#10 +
'' + #13#10 +
'$installedCount = 0' + #13#10 +
'$removedCount = 0' + #13#10 +
'$failCount = 0' + #13#10 +
'' + #13#10;
// Process each printer: install, remove, or skip
for I := 0 to GetArrayLength(PrinterDataArray) - 1 do
begin
// If was installed but now unchecked - REMOVE
if PrinterDataArray[I].IsInstalled and (not PrinterSelectionPage.Values[I]) then
begin
PSScript := PSScript +
'if (Remove-NetworkPrinter -PrinterName "' + PrinterDataArray[I].PrinterName + '" ' +
'-PortAddress "' + PrinterDataArray[I].FQDN + '") {' + #13#10 +
' $removedCount++' + #13#10 +
'} else {' + #13#10 +
' $failCount++' + #13#10 +
'}' + #13#10;
end
// If not installed and now checked - INSTALL
else if (not PrinterDataArray[I].IsInstalled) and PrinterSelectionPage.Values[I] then
begin
PSScript := PSScript +
'if (Install-NetworkPrinter -PrinterName "' + PrinterDataArray[I].PrinterName + '" ' +
'-PortAddress "' + PrinterDataArray[I].FQDN + '" ' +
'-Vendor "' + PrinterDataArray[I].Vendor + '" ' +
'-Model "' + PrinterDataArray[I].Model + '") {' + #13#10 +
' $installedCount++' + #13#10 +
'} else {' + #13#10 +
' $failCount++' + #13#10 +
'}' + #13#10;
end;
// If state hasn't changed - SKIP (no code generated)
end;
// Add summary
PSScript := PSScript +
'' + #13#10 +
'Write-Host ""' + #13#10 +
'Write-Host "========================================" -ForegroundColor Cyan' + #13#10 +
'Write-Host " Operation Complete" -ForegroundColor Cyan' + #13#10 +
'Write-Host "========================================" -ForegroundColor Cyan' + #13#10 +
'Write-Host ""' + #13#10 +
'if ($installedCount -gt 0) {' + #13#10 +
' Write-Host " Printers installed: $installedCount" -ForegroundColor Green' + #13#10 +
'}' + #13#10 +
'if ($removedCount -gt 0) {' + #13#10 +
' Write-Host " Printers removed: $removedCount" -ForegroundColor Magenta' + #13#10 +
'}' + #13#10 +
'if ($failCount -gt 0) {' + #13#10 +
' Write-Host " Failed operations: $failCount" -ForegroundColor Red' + #13#10 +
'}' + #13#10 +
'if ($installedCount -eq 0 -and $removedCount -eq 0 -and $failCount -eq 0) {' + #13#10 +
' Write-Host " No changes were made" -ForegroundColor Gray' + #13#10 +
'}' + #13#10 +
'Write-Host ""' + #13#10 +
'Write-Host "Press any key to close..." -ForegroundColor Gray' + #13#10 +
'$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")';
// Save and execute script
TempScriptPath := ExpandConstant('{tmp}\install_printers.ps1');
SaveStringToFile(TempScriptPath, PSScript, False);
Exec('powershell.exe',
'-NoProfile -ExecutionPolicy Bypass -File "' + TempScriptPath + '"',
'', SW_SHOW, ewWaitUntilTerminated, ResultCode);
DeleteFile(TempScriptPath);
end;
end;
// Skip directory selection
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if PageID = wpSelectDir then
Result := True;
end;