PowerShell GUI添加打印服务器ComboBox实现打印机列表联动
核心错误说明
你修改后的代码存在以下问题,导致功能无法正常运行:
- 变量初始化顺序错误:脚本最顶部定义
$printserver时,$cmbx_Server下拉框控件还未创建,且双引号内直接引用对象属性的写法不会被PowerShell正确解析,$printserver从初始化开始就是无效值 - 事件逻辑缺失:下拉框的选中切换事件仅做了文本打印,没有实现「清空旧打印机列表→拉取选中服务器的打印机列表→填充到ListBox」的核心逻辑
- 按钮事件语法错误:「Select Server」按钮的点击代码将PowerShell命令字符串错误作为参数传给下拉框属性,完全不会执行打印机查询操作
- 启动逻辑错误:窗体加载阶段直接尝试读取未选中服务器的打印机列表,必然触发报错
- 全局变量未动态更新:安装、设为默认打印机等事件中引用的
$printserver始终是初始化时的无效值,不会随下拉框选择变化
修正后可运行完整代码
### Variables # 定义打印服务器列表 $printServerList = @('Printserver1','Printserver2','Printserver3','Printserver4','Printserver5','Printserver6','Printserver7','Printserver8','Printserver9','Printserver0') ### Hide PowerShell Console Add-Type -Name Window -Namespace Console -MemberDefinition ' [DllImport("Kernel32.dll")] public static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); ' $consolePtr = [Console.Window]::GetConsoleWindow() [Console.Window]::ShowWindow($consolePtr, 0) ### GUI Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Application]::EnableVisualStyles() $Form = New-Object system.Windows.Forms.Form $Form.ClientSize = '350,450' $Form.text = "Printer Install Tool" $Form.TopMost = $false $lbl_Server = New-Object system.Windows.Forms.Label $lbl_Server.text = "Print Server" $lbl_Server.AutoSize = $true $lbl_Server.width = 25 $lbl_Server.height = 10 $lbl_Server.location = New-Object System.Drawing.Point(11,16) $lbl_Server.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10) $cmbx_Server = New-Object system.Windows.Forms.ComboBox $cmbx_Server.text = "Choose Server" $cmbx_Server.width = 320 $cmbx_Server.height = 30 $printServerList | ForEach-Object {[void] $cmbx_Server.Items.Add($_)} $cmbx_Server.location = New-Object System.Drawing.Point(11,46) $cmbx_Server.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10) $cmbx_Server.DropDownStyle = 'DropDownList' $btn_Cancel = New-Object system.Windows.Forms.Button $btn_Cancel.text = "Close" $btn_Cancel.width = 100 $btn_Cancel.height = 30 $btn_Cancel.location = New-Object System.Drawing.Point(225,410) $btn_Cancel.Font = 'Microsoft Sans Serif,10' $btn_Install = New-Object system.Windows.Forms.Button $btn_Install.text = "Install printer" $btn_Install.width = 100 $btn_Install.height = 30 $btn_Install.location = New-Object System.Drawing.Point(10,410) $btn_Install.Font = 'Microsoft Sans Serif,10' $btn_Default = New-Object system.Windows.Forms.Button $btn_Default.text = "Set as Default" $btn_Default.width = 100 $btn_Default.height = 30 $btn_Default.location = New-Object System.Drawing.Point(117,410) $btn_Default.Font = 'Microsoft Sans Serif,10' $txtBox_Location = New-Object system.Windows.Forms.TextBox $txtBox_Location.multiline = $false $txtBox_Location.width = 147 $txtBox_Location.height = 20 $txtBox_Location.location = New-Object System.Drawing.Point(179,110) $txtBox_Location.Font = 'Microsoft Sans Serif,8' $txtBox_Location.ReadOnly = $true $listBox_Printers = New-Object system.Windows.Forms.ListBox $listBox_Printers.text = "listBox" $listBox_Printers.width = 159 $listBox_Printers.height = 250 $listBox_Printers.location = New-Object System.Drawing.Point(11,110) $lbl_ChoosePrinter = New-Object system.Windows.Forms.Label $lbl_ChoosePrinter.text = "Choose a printer" $lbl_ChoosePrinter.AutoSize = $true $lbl_ChoosePrinter.width = 25 $lbl_ChoosePrinter.height = 10 $lbl_ChoosePrinter.location = New-Object System.Drawing.Point(11,90) $lbl_ChoosePrinter.Font = 'Microsoft Sans Serif,10' $lbl_PrinterLoc = New-Object system.Windows.Forms.Label $lbl_PrinterLoc.text = "Printer location" $lbl_PrinterLoc.AutoSize = $true $lbl_PrinterLoc.width = 25 $lbl_PrinterLoc.height = 10 $lbl_PrinterLoc.location = New-Object System.Drawing.Point(179,90) $lbl_PrinterLoc.Font = 'Microsoft Sans Serif,10' $Form.controls.AddRange(@($btn_Cancel,$btn_Install,$txtBox_Location,$listBox_Printers,$lbl_ChoosePrinter,$lbl_PrinterLoc,$btn_Default,$lbl_Server,$cmbx_Server)) ### Eventhandlers # 下拉框选中服务器时自动加载对应打印机列表 $cmbx_Server.Add_SelectedIndexChanged({ # 清空旧列表 $listBox_Printers.Items.Clear() $txtBox_Location.Clear() $selectedServer = $cmbx_Server.SelectedItem.ToString() try { # 拉取选中服务器的打印机 $printers = Get-Printer -ComputerName $selectedServer -ErrorAction Stop | Select-Object -Property Location, Name foreach($printer in $printers){ [void]$listBox_Printers.Items.Add($printer.Name) } } catch { [System.Windows.Forms.MessageBox]::Show("无法连接到打印服务器 $selectedServer : $_", "连接错误", "OK", "Error") } }) $listBox_Printers.Add_SelectedIndexChanged({ if ($listBox_Printers.SelectedItem -and $cmbx_Server.SelectedItem) { $printName = $listBox_Printers.SelectedItem.ToString() $selectedServer = $cmbx_Server.SelectedItem.ToString() $txtBox_Location.Text = (Get-Printer -ComputerName $selectedServer -Name $printName).Location } }) $btn_Default.Add_Click({ if (-not $cmbx_Server.SelectedItem -or -not $listBox_Printers.SelectedItem) { [System.Windows.Forms.MessageBox]::Show("请先选择打印服务器和打印机", "提示", "OK", "Warning") return } $selectedServer = $cmbx_Server.SelectedItem.ToString() $printName = $listBox_Printers.SelectedItem.ToString() # 兼容新旧版本Windows的默认打印机设置逻辑 Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows' -Name "LegacyDefaultPrinterMode" -Value 1 -ErrorAction SilentlyContinue (New-Object -ComObject WScript.Network).SetDefaultPrinter("\\$selectedServer\$printName") [System.Windows.Forms.MessageBox]::Show("已将 $printName 设置为默认打印机", "操作成功", "OK", "Information") }) $btn_Cancel.Add_Click({ $Form.Close() }) $btn_Install.Add_Click({ if (-not $cmbx_Server.SelectedItem -or -not $listBox_Printers.SelectedItem) { [System.Windows.Forms.MessageBox]::Show("请先选择打印服务器和打印机", "提示", "OK", "Warning") return } $selectedServer = $cmbx_Server.SelectedItem.ToString() $printName = $listBox_Printers.SelectedItem.ToString() try { Add-Printer -ConnectionName "\\$selectedServer\$printName" -ErrorAction Stop [System.Windows.Forms.MessageBox]::Show("打印机 $printName 安装成功", "操作成功", "OK", "Information") } catch { # 兼容旧系统用rundll32方式安装 rundll32 printui.dll,PrintUIEntry /in /n "\\$selectedServer\$printName" } }) [void]$Form.ShowDialog()
改动说明
- 移除了多余的「Select Server」按钮,选中下拉框选项后自动加载对应打印机列表,操作更顺畅
- 所有事件中动态获取当前选中的服务器,不再依赖初始化时的全局无效变量
- 增加了空选择校验、服务器连接错误提示、操作成功提示,交互更友好
- 修复了原修改版中重复的打印服务器列表项,将下拉框设为仅可选择不可编辑,避免输入无效值
- 兼容新旧版本Windows的打印机安装、默认打印机设置逻辑
- 位置文本框设为只读,避免用户误修改
内容的提问来源于stack exchange,提问作者PCMedicJAX
相关产品推荐
相关产品推荐

