TCP/IP printer installs but GUI is not refreshed

Hi All, newbie here. Trying to create a powershell script to add network printers.
All works well except that when the Install Printer button is clicked, the GUI freezes and can’t be closed. The printer installs successfully though. I need the process to end cleanly and the button enabled back to install another printer.

Pls help. thank you.

# Import necessary assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Function to read INI file
function Read-INIFile {
    param ([string]$path)
    $ini = @{}
    $currentSection = $null
    foreach ($line in Get-Content $path) {
        $line = $line.Trim()
        if ($line -match '^\[(.+?)\]$') {
            $currentSection = $matches[1]
            $ini[$currentSection] = @{}
        } elseif ($line -match '^(.+?)=(.+)$' -and $currentSection) {
            $ini[$currentSection][$matches[1].Trim()] = $matches[2].Trim()
        }
    }
    return $ini
}

# Function to install TCP/IP printer
function Install-Printer {
    param (
        [string]$printerName,
        [string]$ipAddress,
        [string]$portName,
        [string]$driverName
    )

    try {
        # Create a new TCP/IP printer port if it doesn't already exist
        if (-not (Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue)) {
            Add-PrinterPort -Name $portName -PrinterHostAddress $ipAddress
        }

        # Install the printer with the specified driver
        if (-not (Get-Printer -Name $printerName -ErrorAction SilentlyContinue)) {
            Add-Printer -Name $printerName -PortName $portName -DriverName $driverName
            return "Printer $printerName installed successfully."
        } else {
            return "Printer $printerName already exists."
        }
    } catch {
        # Log the detailed error message
        $errorMessage = "Error while installing printer: $_"
        Write-Host $errorMessage  # You can also log this to a file if needed
        return $errorMessage
    }
}

# Load printer configurations from the INI file
$iniFilePath = "C:\Printers.ini"
$printersConfig = Read-INIFile -path $iniFilePath

# Check if the INI file has data
if ($printersConfig.Count -eq 0) {
    [System.Windows.Forms.MessageBox]::Show("No printers found in configuration.", "Warning", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
    exit
}

# Create GUI
$form = New-Object System.Windows.Forms.Form
$form.Text = "TCP/IP Printer Installer"
$form.Size = New-Object System.Drawing.Size(500, 280)
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$form.BackColor = [System.Drawing.Color]::FromArgb(117, 192, 199)

# ComboBox for Printer selection
$comboBox = New-Object System.Windows.Forms.ComboBox
$comboBox.Location = New-Object System.Drawing.Point(20, 20)
$comboBox.Size = New-Object System.Drawing.Size(440, 40)
$comboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$comboBox.DisplayMember = 'DisplayText'

# Add printers to ComboBox
foreach ($printerName in $printersConfig.Keys) {
    $printerConfig = $printersConfig[$printerName]
    if ($printerConfig -and $printerConfig['PrinterName'] -and $printerConfig['IPAddress'] -and $printerConfig['PortName'] -and $printerConfig['DriverName']) {
        $printerObject = New-Object PSObject -Property @{
            PrinterName  = $printerConfig['PrinterName']
            PrinterModel = $printerConfig['PrinterModel']
            IPAddress    = $printerConfig['IPAddress']
            PortName     = $printerConfig['PortName']
            Location     = $printerConfig['Location']
            DriverName   = $printerConfig['DriverName']
            DisplayText  = "$($printerConfig['PrinterName']) - $($printerConfig['Location'])"
        }
        $comboBox.Items.Add($printerObject)
    }
}

$form.Controls.Add($comboBox)

# Label to display selected printer details
$detailsLabel = New-Object System.Windows.Forms.Label
$detailsLabel.Location = New-Object System.Drawing.Point(70, 70)
$detailsLabel.Size = New-Object System.Drawing.Size(340, 80)
$detailsLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
$form.Controls.Add($detailsLabel)

# Button to Install Printer
$installButton = New-Object System.Windows.Forms.Button
$installButton.Text = "Install Selected Printer"
$installButton.Location = New-Object System.Drawing.Point(120, 160)
$installButton.Size = New-Object System.Drawing.Size(250, 40)
$installButton.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 10, [System.Drawing.FontStyle]::Bold)
$form.Controls.Add($installButton)

# ComboBox Selection Event to show printer details
$comboBox.Add_SelectedIndexChanged({
    $selectedPrinter = $comboBox.SelectedItem
    if ($selectedPrinter) {
        $detailsLabel.Text = "Model: $($selectedPrinter.PrinterModel)`n" +
                             "Location: $($selectedPrinter.Location)`n" +
                             "IP Address: $($selectedPrinter.IPAddress)`n" +
                             "Driver: $($selectedPrinter.DriverName)"
    } else {
        $detailsLabel.Text = ""
    }
})

$installButton.Add_Click({
    $selectedPrinter = $comboBox.SelectedItem
    if ($selectedPrinter) {
        Write-Host "Selected Printer Name: $($selectedPrinter.PrinterName)"
        Write-Host "Selected Printer IP: $($selectedPrinter.IPAddress)"
        Write-Host "Selected Printer Port: $($selectedPrinter.PortName)"
        Write-Host "Selected Printer Driver: $($selectedPrinter.DriverName)"
        
        Install-Printer -driverName $($selectedPrinter.DriverName) -ipAddress $($selectedPrinter.IPAddress) -portName $($selectedPrinter.PortName) -printerName $($selectedPrinter.PrinterName)

        # Ensure values are not empty
        if (-not $selectedPrinter.IPAddress -or -not $selectedPrinter.PortName -or -not $selectedPrinter.DriverName) {
            Write-Host "One or more properties are missing for the selected printer."
            return
        }
        # After starting the job, re-enable the button and reset text after a short delay
        
        $installButton.Text = "Install Selected Printer"
        $installButton.Enabled = $true
        
        # Optionally display a message that installation has started
        [System.Windows.Forms.MessageBox]::Show("Printer installation has started.", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
        
        # Close the form if desired
        $form.Close()  # Close the form after installation starts
    } else {
        [System.Windows.Forms.MessageBox]::Show("Please select a printer to install.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
    }
})

# Show the form
$form.Add_Shown({ $form.Activate() })
[void]$form.ShowDialog()

Hi, welcome to the forum :wave:

What have you done so far to troubleshoot the script?

Clicking the button performs a number of actions, you said it installs the printer which suggests it’s getting as far as Install-Printer.
Does the “Printer installation has started” message pop up? Have you checked to make sure the message isn’t popping up under the form and thus making the GUI appear frozen, even though it’s just waiting for you to acknowledge the message?

Did you write this from scratch or is it ChatGPT generated?

2 Likes

oh my… how silly of me! thanks for the “hint” matt-bloomfield.
i was all these while running/testing/amending/troubleshooting the script using PS ISE… no wonder the GUI appears frozen.

all is well now… i can go on to add more stuff to the script eg SNMP community, paper size and color (b&w) etc…

thanks much!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.