PowerShell GUI:单行文本框内容移动异常问题求助
问题描述
脚本在输入多台计算机(多行内容)时运行正常,但仅输入一行(例如Computer 201)时,结果会显示为1。目前已禁用PING功能,需先解决单行输入失效的问题。
问题原因
核心问题出在输入内容的过滤逻辑上:
- 输入多行内容时,
($Inputbox.Text -split '\r?\n')生成多元素数组,.Trim()处理每个元素后,-ne ''会自动执行元素级过滤,保留非空内容。 - 输入单行内容时,
-split生成单元素数组,此时-ne ''会变成整个数组与空字符串的比较,返回布尔值$true,最终$ref数组中存放的是$true,而$true在字符串输出时会显示为1。
另外,原循环逻辑依赖数组初始长度,同时在循环中修改数组长度,存在索引异常的潜在风险。
修复方案
- 修正过滤逻辑:使用
Where-Object明确过滤空元素,避免单元素数组时的布尔值问题。 - 优化循环逻辑:采用遍历元素的方式替代依赖数组长度的循环,避免索引错误。
修复后的完整代码:
# Load required assemblies [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") # Drawing form and controls $Harvester = New-Object System.Windows.Forms.Form $Harvester.Text = "Ping Computers" $Harvester.Size = New-Object System.Drawing.Size(490,300) $Harvester.FormBorderStyle = "FixedDialog" $Harvester.TopMost = $true $Harvester.MaximizeBox = $false $Harvester.MinimizeBox = $false $Harvester.ControlBox = $true $Harvester.StartPosition = "CenterScreen" $Harvester.Font = "Segoe UI" #======================== INPUTBOX - Computers ========================# $label_message2 = New-Object System.Windows.Forms.Label $label_message2.Location = New-Object System.Drawing.Size(20,10) $label_message2.Size = New-Object System.Drawing.Size(100,15) $label_message2.Text = "Computers" $Harvester.Controls.Add($label_message2) # Inputbox $Inputbox = New-Object System.Windows.Forms.TextBox $Inputbox.Multiline = $True; $Inputbox.Location = New-Object System.Drawing.Size(20,30) $Inputbox.Size = New-Object System.Drawing.Size(200,150) $Inputbox.ScrollBars = "Vertical" $Harvester.Controls.Add($Inputbox) #======================== INPUTBOX - Completed ========================# $label_message_success = New-Object System.Windows.Forms.Label $label_message_success.Location = New-Object System.Drawing.Size(250,10) $label_message_success.Size = New-Object System.Drawing.Size(100,15) $label_message_success.Text = "Successful" $Harvester.Controls.Add($label_message_success) # Inputbox $Inputbox_success = New-Object System.Windows.Forms.TextBox $Inputbox_success.Multiline = $True; $Inputbox_success.Location = New-Object System.Drawing.Size(250,30) $Inputbox_success.Size = New-Object System.Drawing.Size(200,150) $Inputbox_success.ScrollBars = "Vertical" $Harvester.Controls.Add($Inputbox_success) #======================== Ping ========================# $button_Ping = New-Object System.Windows.Forms.Button $button_Ping.Location = New-Object System.Drawing.Size(120,200) $button_Ping.Size = New-Object System.Drawing.Size(80,32) $button_Ping.TextAlign = "MiddleCenter" $button_Ping.Text = "Ping" $button_Ping.Add_Click({ If ($Inputbox.TextLength -eq 0){ Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.MessageBox]::Show('Please enter at least 1 computer to perform this action') Return } # 修正过滤逻辑:使用Where-Object明确过滤空元素 [collections.arraylist] $ref = ($Inputbox.Text -split '\r?\n').Trim() | Where-Object { $_ -ne '' } if(-not $ref) { return } # if the textbox is empty, don't do anything # 优化循环:遍历每个元素,避免索引错误 foreach ($computer in $ref.Clone()) { #if(Test-Connection $computer -Quiet) { $Inputbox_success.Text += $computer + [environment]::NewLine $ref.Remove($computer) #} $Inputbox.Text = $ref | Out-String $Inputbox, $Inputbox_success | ForEach-Object Refresh } }) $Harvester.Controls.Add($button_Ping) # show form $Harvester.Add_Shown({$Harvester.Activate()}) [void] $Harvester.ShowDialog()
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

