如果选择了按钮,下面的 PS 不会填充变量。但是,如果选择按键 1-2,则选择打印机。
该按钮适用于语言选择的按钮选择,但不适用于打印机选择。按键 1-2 正在工作。一旦通过 $_.打印机名称在框中选择了打印机,就不会填充 $global:printerChoice 的变量。里面是空的。
Add-Type -AssemblyName "System.Windows.Forms"
# Initialize global variables
$language = 0
$printerChoice = ""
# Language Selection Form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select Language'
$form.Size = New-Object System.Drawing.Size(300, 200)
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen # Center the form
$form.TopMost = $true # Keep the form in the foreground
$form.KeyPreview = $true # Ensure the form captures key presses
# Create a label for instructions
$label = New-Object System.Windows.Forms.Label
$label.Text = 'Select your language (1: English, 2: Español):'
$label.Location = New-Object System.Drawing.Point(10, 10)
$label.Size = New-Object System.Drawing.Size(280, 40)
$form.Controls.Add($label)
# Create buttons for each language
$buttonEnglish = New-Object System.Windows.Forms.Button
$buttonEnglish.Text = "1. English"
$buttonEnglish.Location = New-Object System.Drawing.Point(10, 60)
$buttonEnglish.Size = New-Object System.Drawing.Size(260, 40)
$buttonEnglish.Add_Click({
$global:language = 1
Write-Host "Language selected: English (1)"
$form.Close()
})
$form.Controls.Add($buttonEnglish)
$buttonSpanish = New-Object System.Windows.Forms.Button
$buttonSpanish.Text = "2. Español"
$buttonSpanish.Location = New-Object System.Drawing.Point(10, 110)
$buttonSpanish.Size = New-Object System.Drawing.Size(260, 40)
$buttonSpanish.Add_Click({
$global:language = 2
Write-Host "Language selected: Español (2)"
$form.Close()
})
$form.Controls.Add($buttonSpanish)
# KeyDown event for capturing keyboard and numpad inputs
$form.Add_KeyDown({
$key = $_.KeyCode
Write-Host "Key pressed: $key"
if ($key -eq [System.Windows.Forms.Keys]::D1 -or $key -eq [System.Windows.Forms.Keys]::NumPad1) {
$global:language = 1
Write-Host "Language selected: English (1)"
$form.Close()
} elseif ($key -eq [System.Windows.Forms.Keys]::D2 -or $key -eq [System.Windows.Forms.Keys]::NumPad2) {
$global:language = 2
Write-Host "Language selected: Español (2)"
$form.Close()
}
})
# Show the form for language selection
$form.ShowDialog()
# Output the selected language for debugging
Write-Host "Selected Language: $global:language"
# Set language messages based on selection
if ($global:language -eq 2) {
$langMessage = @{
"choosePrinter" = "Seleccione su impresora desde la lista."
"setDefault" = "La impresora predeterminada ha sido configurada."
"orientationLandscape" = "La orientación de la impresora está en horizontal."
"orientationNotLandscape" = "La orientación de la impresora no está en horizontal. Comuníquese con el supervisor coordinador o con el departamento de TI para configurarla."
"noPrinterSelected" = "No se seleccionó ninguna impresora. Seleccione una impresora predeterminada para sus facturas."
"printerError" = "Error al obtener información de la impresora. Verifique la impresora seleccionada."
"methodInvocationError" = "Hubo un error al configurar la impresora predeterminada."
"orientationError" = "Error al verificar la orientación de la impresora."
}
} else {
$langMessage = @{
"choosePrinter" = "Please choose your printer from the list."
"setDefault" = "The default printer has been set."
"orientationLandscape" = "The printer orientation is in Landscape."
"orientationNotLandscape" = "The printer orientation is not in Landscape. Contact Supervisor Coordinator or IT to set the printer orientation."
"noPrinterSelected" = "No printer selected. Please Select a default printer for your invoices."
"printerError" = "Error getting printer information. Please check the selected printer."
"methodInvocationError" = "There was an error setting the default printer."
"orientationError" = "Error checking printer orientation."
}
}
# Fetch the list of printers
$printers = Get-Printer | Select-Object Name
$printersCount = $printers.Count
Write-Host "Printers found: $printersCount"
# Create the form for printer selection
$printerForm = New-Object System.Windows.Forms.Form
$printerForm.Text = $langMessage["choosePrinter"]
$printerForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen # Center the form
$printerForm.TopMost = $true # Keep the form in the foreground
# Calculate the size of the printer form based on the number of printers
$buttonHeight = 40
$padding = 20
$formHeight = $printersCount * ($buttonHeight + $padding) + 100 # Add extra space for form controls
$printerForm.Size = New-Object System.Drawing.Size(300, $formHeight)
$printerForm.KeyPreview = $true # Ensure the form captures key presses
# Create buttons for each printer
$buttons = @()
$yOffset = 60
$printers | ForEach-Object -Begin {
$yOffset = 60 # Start position for the first button
} -Process {
Write-Host "Creating button for printer: $($_.Name)" # Debugging message to check printer name
$button = New-Object System.Windows.Forms.Button
$button.Text = "$($printers.IndexOf($_) + 1). $($_.Name)"
$button.Location = New-Object System.Drawing.Point(10, $yOffset)
$button.Size = New-Object System.Drawing.Size(260, $buttonHeight)
$button.Add_Click({
Write-Host "Button clicked for printer: $($_.Name)" # Debugging button click
$global:printerChoice = $_.Name
Write-Host "Printer selected: $global:printerChoice" # Verify the selection
$printerForm.Close()
})
$printerForm.Controls.Add($button)
$yOffset += $buttonHeight + $padding # Increase Y position for next button
$buttons += $button
}
# KeyDown event for capturing keyboard and numpad inputs for printer selection
$printerForm.Add_KeyDown({
$key = $_.KeyCode
Write-Host "Key pressed for printer selection: $key"
$index = -1
# Check for number key press
if ($key -ge [System.Windows.Forms.Keys]::D1 -and $key -le [System.Windows.Forms.Keys]::D9) {
$index = $key - [System.Windows.Forms.Keys]::D1
} elseif ($key -ge [System.Windows.Forms.Keys]::NumPad1 -and $key -le [System.Windows.Forms.Keys]::NumPad9) {
$index = $key - [System.Windows.Forms.Keys]::NumPad1
}
if ($index -ge 0 -and $index -lt $printersCount) {
Write-Host "Selected printer from key press: $($printers[$index].Name)" # Debugging key press
$global:printerChoice = $printers[$index].Name
$printerForm.Close()
}
})
# Show the printer selection form
$printerForm.ShowDialog()
# Output the selected printer for debugging
Write-Host "Selected Printer: $global:printerChoice"
# Proceed with printer selection if valid choice is made
if (-not $printerChoice) {
[System.Windows.Forms.MessageBox]::Show($langMessage["noPrinterSelected"], "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
return
}
# Set the printer as the default
try {
Write-Host "Attempting to set $global:printerChoice as default printer."
$Printer = Get-CimInstance -Class Win32_Printer -Filter "Name='$global:printerChoice'"
if (-not $Printer) {
Write-Host "Error: Printer not found."
[System.Windows.Forms.MessageBox]::Show($langMessage["printerError"], "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
return
}
Invoke-CimMethod -InputObject $Printer -MethodName SetDefaultPrinter | Out-Null
Write-Host "Default printer set to: $global:printerChoice"
[System.Windows.Forms.MessageBox]::Show("$global:printerChoice $($langMessage['setDefault'])", "Success", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
} catch {
Write-Host "Error setting default printer: $_"
[System.Windows.Forms.MessageBox]::Show($langMessage["methodInvocationError"], "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
}
调试输出:
选择语言:英语(1)
取消
选择的语言:1
找到打印机:5
为打印机创建按钮:Snagit 2024
为打印机创建按钮:OneNote for Windows 10
为打印机创建按钮:PDF Writer - bioPDF
为打印机创建按钮:OneNote(桌面)
为打印机创建按钮:HP LaserJet Pro M402-M403 n-dne PCL 6
单击打印机按钮:
选择的打印机:
取消
所选打印机:
好的
正如所评论的,在像
Add_Click({..})
这样的事件处理程序中,$_
自动变量不是您正在迭代的打印机,而是处理程序的EventArgs。
在 Add-Click() 事件处理程序中,这将是一个描述鼠标单击本身的对象(位置、左键或右键等)
为了将打印机名称与相应的按钮很好地保持在一起,我建议将此打印机名称存储在按钮自己的
.Tag
属性中:
尝试:
$printers = Get-Printer | Select-Object -ExpandProperty Name # just the name. for short use (Get-Printer).Name
# Create buttons for each printer
$buttonHeight = 40
$padding = 20
$yOffset = 60 # Start position for the first button
$index = 1 # for the button text
# your code does not show any reason for collecting the buttons in a variable $buttons, but
# if you do need it, collect the array like below and do not use $buttons += $button
$buttons = $printers | ForEach-Object {
Write-Host "Creating button for printer: $_" # Debugging message to check printer name
$button = [System.Windows.Forms.Button]::new()
$button.Text = '{0}. {1}' -f $index++, $_
$button.Tag = $_ # store the printer name in the .Tag property
$button.Location = [System.Drawing.Point]::new(10, $yOffset)
$button.Size = [System.Drawing.Size]::new(260, $buttonHeight)
$button.Add_Click({
# now, the button has the actual printername in its .Tag property
$printerName = $this.Tag # for convenience
Write-Host "Button clicked for printer: $printerName" # Debugging button click
$global:printerChoice = $printerName # try $script: scope instead
Write-Host "Printer selected: $global:printerChoice" # Verify the selection
$printerForm.Close()
})
$printerForm.Controls.Add($button)
$yOffset += $buttonHeight + $padding # Increase Y position for next button
$button # output the new object to be captured in variable $buttons
}
我在这里使用新语法来定义 System.Drawing 对象。当然,
New-Object ..
也可以,不过这样应该会快一点。不过,您需要 PowerShell 版本 5 及更高版本