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

PowerShell带倒计时可取消更新对话框脚本异常排查

问题根因
  • 窗体假死无法点击按钮:你使用$Counter_Form.Show()非模态显示窗体后,直接在主线程执行Start-Sleep阻塞执行,Windows UI消息循环无法处理鼠标点击、按钮交互等事件,导致界面无响应。同时你在循环内反复调用Show()也属于错误用法,窗体只需要显示一次。
  • $cancel变量始终为$false:按钮点击事件的脚本块运行在独立的子作用域中,直接给$cancel赋值只会修改子作用域内的局部变量,不会改动外层作用域的同名变量,因此外层循环永远读不到你在点击事件里设置的$true值。
修复方案

不要用Start-Sleep做阻塞式等待,改用Windows Forms原生的Timer控件实现倒计时,计时逻辑运行在UI消息循环中不会阻塞交互;同时用窗体自带的DialogResult属性判断用户操作,避免手动处理跨作用域变量的问题。

修正后的完整可运行代码如下:

# 调整倒计时时长(单位:秒)
$delay = 30

Add-Type -AssemblyName System.Windows.Forms

$Counter_Form = New-Object System.Windows.Forms.Form
$Counter_Form.Text = "Warning"
$Counter_Form.Width = 350
$Counter_Form.Height = 150
$Counter_Form.StartPosition = "CenterScreen"
$Counter_Form.TopMost = $true
$Counter_Form.FormBorderStyle = 'FixedDialog'
$Counter_Form.MaximizeBox = $false
$Counter_Form.MinimizeBox = $false

$Counter_Label2 = New-Object System.Windows.Forms.Label
$Counter_Label2.Text = "Please save all your work"
$Counter_Label2.AutoSize = $true
$Counter_Label2.Location = New-Object System.Drawing.Point(90,30)

$Counter_Label = New-Object System.Windows.Forms.Label
$Counter_Label.AutoSize = $true
$Counter_Label.Location = New-Object System.Drawing.Point(50,60)

$button1 =  New-Object System.Windows.Forms.Button
$button1.Text = "Cancel Update"
$button1.Location = New-Object System.Drawing.Point(130,80)
$button1.Add_Click({ 
    $Counter_Form.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $Counter_Form.Close()
})

$Counter_Form.Controls.Add($Counter_Label)
$Counter_Form.Controls.Add($Counter_Label2)
$Counter_Form.Controls.Add($button1)

$remaining = $delay
$Counter_Label.Text = "Update will occur in $($remaining) seconds."

# 初始化计时器,间隔1秒触发一次
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.Add_Tick({
    $remaining--
    $Counter_Label.Text = "Update will occur in $($remaining) seconds."
    if ($remaining -le 0) {
        $timer.Stop()
        $Counter_Form.DialogResult = [System.Windows.Forms.DialogResult]::OK
        $Counter_Form.Close()
    }
})
$timer.Start()

# 模态显示窗体,保持UI响应直到窗体关闭
$result = $Counter_Form.ShowDialog()

# 释放资源
$timer.Dispose()
$Counter_Form.Dispose()

# 根据返回结果执行对应逻辑
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    # 在此处写入更新操作的执行逻辑
    Write-Host "开始执行系统更新"
}
else {
    Write-Host "用户已取消更新操作"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 00:57:26