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

PowerShell录屏脚本While循环致GUI无响应,无法终止录屏

解决PowerShell录屏GUI无响应问题(FFmpeg分段录制)

问题根源

你的代码里Start-Recording函数的while循环会阻塞WinForms的UI线程:WaitForExit是同步等待FFmpeg进程结束的操作,加上循环持续执行,导致UI无法处理按钮点击等消息,所以Stop按钮完全没反应。

解决方案:用后台线程执行录制逻辑

把录制的循环逻辑放到独立的后台线程里,让UI线程保持响应。同时完善停止逻辑,确保能立即终止当前正在运行的FFmpeg进程。

修改后的完整代码

Add-Type -AssemblyName System.Windows.Forms

$ffmpegPath = "C:\ffmpeg\bin\ffmpeg.exe"
$outputFilePrefix = "output"
$recordDuration = 10  
$global:ffmpegProcess = $null
$global:recordingInProgress = $false
$global:recordingThread = $null

function Start-Recording {
    $global:recordingInProgress = $true
    $recordIndex = 1
    while ($global:recordingInProgress) {
        $outputFile = "$outputFilePrefix$recordIndex.mp4"
        $processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
        $processStartInfo.FileName = $ffmpegPath
        $processStartInfo.Arguments = "-f gdigrab -framerate 30 -i desktop -c:v mpeg4 -q:v 2 -r 30 -t $recordDuration -y $outputFile" 
        $processStartInfo.UseShellExecute = $false
        $processStartInfo.RedirectStandardOutput = $true
        $processStartInfo.CreateNoWindow = $false
        $global:ffmpegProcess = New-Object System.Diagnostics.Process
        $global:ffmpegProcess.StartInfo = $processStartInfo

        try {
            $global:ffmpegProcess.Start() | Out-Null
            # 异步等待进程退出,避免阻塞线程
            $exitEvent = $global:ffmpegProcess.WaitForExitAsync()
            # 同时检查录制状态,允许中途停止
            while (-not $exitEvent.IsCompleted -and $global:recordingInProgress) {
                Start-Sleep -Milliseconds 100
            }
            if (-not $global:ffmpegProcess.HasExited) {
                $global:ffmpegProcess.Kill()
                $global:ffmpegProcess.WaitForExit()
            }
            $recordIndex++
        } catch {
            Write-Host "录制出错: $_"
        }
    }
}

function Stop-Recording {
    $global:recordingInProgress = $false
    # 终止当前正在运行的FFmpeg进程
    if ($global:ffmpegProcess -and -not $global:ffmpegProcess.HasExited) {
        $global:ffmpegProcess.Kill()
        $global:ffmpegProcess.WaitForExit()
    }
}

# 创建UI界面
$form = New-Object System.Windows.Forms.Form
$form.Text = "分段录屏工具"
$form.Size = New-Object System.Drawing.Size(300,150)
$form.StartPosition = "CenterScreen"

$startBtn = New-Object System.Windows.Forms.Button
$startBtn.Text = "Start Recording"
$startBtn.Location = New-Object System.Drawing.Point(20,30)
$startBtn.Add_Click({
    if (-not $global:recordingInProgress) {
        # 在后台线程启动录制
        $global:recordingThread = [System.Threading.Thread]::new({Start-Recording})
        $global:recordingThread.IsBackground = $true
        $global:recordingThread.Start()
    }
})

$stopBtn = New-Object System.Windows.Forms.Button
$stopBtn.Text = "Stop Recording"
$stopBtn.Location = New-Object System.Drawing.Point(160,30)
$stopBtn.Add_Click({Stop-Recording})

$form.Controls.Add($startBtn)
$form.Controls.Add($stopBtn)

$form.ShowDialog() | Out-Null

关键改进点

  • 使用后台线程执行录制循环,UI线程不再被阻塞,Stop按钮可以正常响应
  • 替换WaitForExit为异步等待+状态检查,允许中途终止当前录制片段
  • 完善停止逻辑,立即杀掉当前运行的FFmpeg进程,而不是等它录完10秒

替代工具建议

如果不想自己维护PowerShell代码,可以考虑这些工具:

  • OBS Studio:支持命令行模式,可以通过脚本控制分段录制,功能强大且稳定
  • ShareX:开源录屏工具,自带PowerShell/命令行接口,支持自定义分段规则
  • FFmpeg直接批处理脚本:放弃WinForms GUI,用控制台脚本+快捷键控制启停(比如用Set-PSReadlineKeyHandler绑定快捷键)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:35:38