PowerShell窗体操作后无法关闭,后台进程残留问题求助
PowerShell窗体关闭后进程残留问题排查与解决
问题原因
- WinForms资源未主动释放:调用
ShowDialog()显示窗体后,窗体对象及关联控件的资源没有被手动释放,.NET垃圾回收机制不会立即清理这些资源,导致PowerShell进程无法正常退出。 - 图片资源未释放:通过
[System.Drawing.Image]::FromFile()加载的图片会占用文件句柄,若不手动释放,会阻止进程正常结束。 - OptOut按钮代码错误:按钮点击事件里的
Start-Process被包裹在引号中,仅作为字符串存在,并未实际执行邮件调用(此为功能bug,不影响进程残留,但需修正)。
解决步骤
- 在窗体关闭后,手动调用
Dispose()方法释放窗体和图片资源。 - 触发强制垃圾回收,确保所有占用资源被彻底清理。
- 修正OptOut按钮的点击事件代码,让邮件调用命令正常执行。
修改后的完整代码
Copy-Item -Path C:\temp\logo.jpg "$env:USERPROFILE\logo.jpg" Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # 创建窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "Logo Information System" $form.Size = New-Object System.Drawing.Size(500, 350) $form.FormBorderStyle = "FixedDialog" $form.ControlBox = $false $form.StartPosition = "CenterScreen" $form.BackColor = "Black" # 加载并设置标题栏图片 $icon = [System.Drawing.Image]::FromFile("$env:USERPROFILE\logo.jpg") $pictureBox = New-Object System.Windows.Forms.PictureBox $pictureBox.Image = $icon $pictureBox.Size = New-Object System.Drawing.Size(94, 94) $pictureBox.Location = New-Object System.Drawing.Point(10, 10) $form.Controls.Add($pictureBox) # 标题标签 $titleLabel = New-Object System.Windows.Forms.Label $titleLabel.Text = "Windows 11 Upgrade Notification" $titleLabel.Font = New-Object System.Drawing.Font("Arial", 14, [System.Drawing.FontStyle]::Bold) $titleLabel.ForeColor = "Red" $titleLabel.BackColor = "Black" $titleLabel.AutoSize = $true $titleLabel.Location = New-Object System.Drawing.Point(120, 40) $form.Controls.Add($titleLabel) # 消息标签 $msgLabel = New-Object System.Windows.Forms.Label $msgLabel.Text = "Add here anything?" $msgLabel.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold) $msgLabel.ForeColor = "Red" $msgLabel.BackColor = "Black" $msgLabel.AutoSize = $true $msgLabel.Location = New-Object System.Drawing.Point(120, 70) $form.Controls.Add($msgLabel) # 文本框(居中) $textBox = New-Object System.Windows.Forms.TextBox $textBox.Multiline = $true $textBox.ReadOnly = $true $textBox.Text = "Windows 11 is being rolled out in your environment. Please select an option below." $textBox.Font = New-Object System.Drawing.Font("Arial", 12) $textBox.Size = New-Object System.Drawing.Size(460, 100) $textBox.Location = New-Object System.Drawing.Point(10, 110) $textBox.TextAlign = "Center" $form.Controls.Add($textBox) # 按钮 $btnStartUpgrade = New-Object System.Windows.Forms.Button $btnStartUpgrade.Text = "Upgrade Tonight" $btnStartUpgrade.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold) $btnStartUpgrade.ForeColor = "Black" $btnStartUpgrade.BackColor = "Green" $btnStartUpgrade.Size = New-Object System.Drawing.Size(220, 40) $btnStartUpgrade.Location = New-Object System.Drawing.Point(10, 240) $btnStartUpgrade.Add_Click({ Start-Process "mailto:someone@outlook.com?subject=Upgrade Confirmation Notification&body=$env:computername would like to upgrade to Windows 11 tonight at 20:00 followed by an immediate reboot." }) $form.Controls.Add($btnStartUpgrade) $btnOptOut = New-Object System.Windows.Forms.Button $btnOptOut.Text = "Opt-Out of Win 11 upgrade" $btnOptOut.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold) $btnOptOut.ForeColor = "Black" $btnOptOut.BackColor = "Yellow" $btnOptOut.Size = New-Object System.Drawing.Size(220, 40) $btnOptOut.Location = New-Object System.Drawing.Point(250, 240) $btnOptOut.Add_Click({ # 修正:去掉引号,让命令实际执行 Start-Process "mailto:someone@outlook.com?subject=Opt-Out Request&body=$env:computername would like to opt out of the Windows 11 upgrade." }) $form.Controls.Add($btnOptOut) # 显示窗体 $form.ShowDialog() # 关键:释放窗体和图片资源 $form.Dispose() $icon.Dispose() # 强制触发垃圾回收,确保资源被清理 [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers()
内容的提问来源于stack exchange,提问作者Adam Wifi
相关产品推荐
相关产品推荐

