You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell GUI脚本问题:点击Close按钮无法移除红绿状态图标

Fix for PowerShell GUI Close Button Not Removing Status Icons

Hey there! I took a look at your PowerShell GUI script, and the reason your Close button isn't removing those red/green icons is pretty straightforward:

When you click the Close button, you're creating new PictureBox objects ($pictureBoxRed and $pictureBoxGreen) instead of targeting the ones you already added to the $outputBox during the Check operation. Those new objects don't exist in the form's control collection, so calling Remove() on them does nothing. Additionally, you're not clearing all existing PictureBoxes—you're only trying to remove two specific (unused) variables.

Here's how to fix this, along with some other small improvements to your script:

Step 1: Clean up the Check Button Logic

First, let's fix the Check button to initialize counters properly and avoid re-adding the $outputBox every time:

$Button.Add_Click({
    # Clear existing controls in outputBox instead of removing the whole box
    $outputBox.Controls.Clear()
    $counterpic = 10  # Initialize counter properly
    $counter = 10

    foreach($room in $arrayTPs){
        $roomAlone = $room -split ","
        $roomName = $roomAlone[0]
        $tpIp = $roomAlone[1]

        # Create a single PictureBox instead of two (we'll set the image based on status)
        $statusPic = New-Object Windows.Forms.PictureBox
        $statusPic.Width = 10
        $statusPic.Height = 10
        $statusPic.Location = New-Object System.Drawing.Point(90, $counterpic)

        # Set image based on IP (you can replace this with actual ping logic later!)
        if($tpIp -eq "172.0.0.0"){
            $statusPic.Image = $imggreen
        }
        else{
            $statusPic.Image = $imgred
        }

        # Add the picture box to outputBox
        $outputBox.Controls.Add($statusPic)

        # Optional: Add room name label next to the icon
        $roomLabel = New-Object Windows.Forms.Label
        $roomLabel.Text = $roomName
        $roomLabel.Location = New-Object System.Drawing.Point(10, $counterpic)
        $outputBox.Controls.Add($roomLabel)

        $counterpic += 20
        $counter += 20
    }
    $Form.Refresh()
})

Step 2: Fix the Close Button Logic

Instead of creating new PictureBoxes, just clear all PictureBox controls from the $outputBox:

$cancelButton.Add_Click({
    # Loop through all controls in outputBox and remove PictureBoxes
    $controlsToRemove = $outputBox.Controls | Where-Object { $_ -is [System.Windows.Forms.PictureBox] }
    foreach($control in $controlsToRemove){
        $outputBox.Controls.Remove($control)
    }
    # Optional: Remove all labels too if you added them
    $labelsToRemove = $outputBox.Controls | Where-Object { $_ -is [System.Windows.Forms.Label] }
    foreach($label in $labelsToRemove){
        $outputBox.Controls.Remove($label)
    }
    $Form.Refresh()
})

Full Corrected Script

Here's the complete script with all fixes applied:

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Hardware Checks"
$Form.Size = New-Object System.Drawing.Size(600,600)

$arrayTPs = Get-Content -path "C:\Activity monitor\TPs.txt"

# Image Locations
$filered = Get-Item 'C:\Activity monitor\red1.png'
$filegreen = Get-Item 'C:\Activity monitor\green1.png'
$imgred = [System.Drawing.Image]::FromFile($filered)
$imggreen = [System.Drawing.Image]::FromFile($filegreen)

$outputBox = New-Object System.Windows.Forms.TextBox
$outputBox.Location = New-Object System.Drawing.Size(10,200)
$outputBox.Size = New-Object System.Drawing.Size(565,200)
$outputBox.MultiLine = $True
$outputBox.ScrollBars = "Vertical"
$Form.Controls.Add($outputBox)

$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(450,30)
$Button.Size = New-Object System.Drawing.Size(75,75)
$Button.Text = "Check"
$Button.Add_Click({
    $outputBox.Controls.Clear()
    $counterpic = 10
    $counter = 10

    foreach($room in $arrayTPs){
        $roomAlone = $room -split ","
        $roomName = $roomAlone[0]
        $tpIp = $roomAlone[1]

        $statusPic = New-Object Windows.Forms.PictureBox
        $statusPic.Width = 10
        $statusPic.Height = 10
        $statusPic.Location = New-Object System.Drawing.Point(90, $counterpic)

        if($tpIp -eq "172.0.0.0"){
            $statusPic.Image = $imggreen
        }
        else{
            $statusPic.Image = $imgred
        }

        $outputBox.Controls.Add($statusPic)

        $roomLabel = New-Object Windows.Forms.Label
        $roomLabel.Text = $roomName
        $roomLabel.Location = New-Object System.Drawing.Point(10, $counterpic)
        $outputBox.Controls.Add($roomLabel)

        $counterpic += 20
        $counter += 20
    }
    $Form.Refresh()
})
$Form.Controls.Add($Button)

$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(450,520)
$cancelButton.Size = New-Object System.Drawing.Size(75,25)
$cancelButton.Text = "Close"
$cancelButton.Add_Click({
    # Remove all PictureBoxes from outputBox
    $controlsToRemove = $outputBox.Controls | Where-Object { $_ -is [System.Windows.Forms.PictureBox] }
    foreach($control in $controlsToRemove){
        $outputBox.Controls.Remove($control)
    }
    # Remove all labels too if needed
    $labelsToRemove = $outputBox.Controls | Where-Object { $_ -is [System.Windows.Forms.Label] }
    foreach($label in $labelsToRemove){
        $outputBox.Controls.Remove($label)
    }
    $Form.Refresh()
})
$Form.Controls.Add($cancelButton)

$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

Key Improvements:

  • Proper Counter Initialization: $counterpic starts at 10 so icons don't overlap at the top.
  • Single PictureBox Object: Instead of creating two PictureBoxes per entry, we create one and set the image based on status—cleaner code.
  • Clear Controls Instead of Re-Adding: The Check button now clears existing controls in $outputBox instead of removing and re-adding the entire text box.
  • Targeted Control Removal: The Close button now finds all existing PictureBoxes (and labels, if you added them) in $outputBox and removes them, which actually clears the icons properly.

Also, note that right now you're just checking if the IP equals 172.0.0.0—you might want to replace that with actual ping logic later, like:

if(Test-Connection -ComputerName $tpIp -Count 1 -Quiet -ErrorAction SilentlyContinue){
    $statusPic.Image = $imggreen
}
else{
    $statusPic.Image = $imgred
}

内容的提问来源于stack exchange,提问作者visar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:29:14