# 冒烟测试:启动应用 → 验证主窗口 → Ctrl+Alt+Q 呼出轮盘 → Esc 关闭轮盘 → 退出 param( [string]$Exe = "src/OneClickRun.App/bin/x64/Debug/net8.0-windows10.0.19041.0/win-x64/OneClickRun.exe" ) $ErrorActionPreference = "Stop" $root = Split-Path -Parent $PSScriptRoot $exePath = Join-Path $root $Exe if (-not (Test-Path $exePath)) { throw "找不到应用: $exePath" } Add-Type @" using System; using System.Text; using System.Runtime.InteropServices; public class WinEnum { public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] public static extern bool EnumWindows(EnumWindowsProc cb, IntPtr lParam); [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint pid); [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder sb, int max); [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); } "@ $script:Wins = New-Object System.Collections.Generic.List[object] $script:TargetPid = 0 $cb = [WinEnum+EnumWindowsProc]{ param($h, $l) $wpid = 0 [void][WinEnum]::GetWindowThreadProcessId($h, [ref]$wpid) if ($wpid -eq $script:TargetPid) { $sb = New-Object System.Text.StringBuilder 256 [void][WinEnum]::GetWindowText($h, $sb, 256) $script:Wins.Add([pscustomobject]@{ Visible = [WinEnum]::IsWindowVisible($h); Title = $sb.ToString() }) } return $true } function Show-Windows { $script:Wins.Clear() [void][WinEnum]::EnumWindows($cb, [IntPtr]::Zero) $script:Wins | ForEach-Object { Write-Host (" visible={0} title='{1}'" -f $_.Visible, $_.Title) } } $proc = Start-Process -FilePath $exePath -PassThru $script:TargetPid = $proc.Id try { Write-Host "已启动 PID=$($proc.Id)" Start-Sleep -Seconds 5 if ($proc.HasExited) { throw "进程提前退出,退出码 $($proc.ExitCode)" } Write-Host "=== 启动后窗口 ===" Show-Windows if (-not ($script:Wins | Where-Object { $_.Title -like '*一键运行*' })) { throw "未找到主窗口" } # 发送 Ctrl+Alt+Q [WinEnum]::keybd_event(0x11, 0, 0, [UIntPtr]::Zero) [WinEnum]::keybd_event(0x12, 0, 0, [UIntPtr]::Zero) [WinEnum]::keybd_event(0x51, 0, 0, [UIntPtr]::Zero) Start-Sleep -Milliseconds 120 [WinEnum]::keybd_event(0x51, 0, 2, [UIntPtr]::Zero) [WinEnum]::keybd_event(0x12, 0, 2, [UIntPtr]::Zero) [WinEnum]::keybd_event(0x11, 0, 2, [UIntPtr]::Zero) Start-Sleep -Seconds 1 Write-Host "=== 按 Ctrl+Alt+Q 后 ===" Show-Windows $wheel = $script:Wins | Where-Object { $_.Title -like '*Wheel*' } if (-not $wheel) { throw "热键未能呼出轮盘窗口" } if (-not $wheel.Visible) { throw "轮盘窗口存在但不可见" } Write-Host "PASS: 轮盘已呼出" # Esc 关闭 [WinEnum]::keybd_event(0x1B, 0, 0, [UIntPtr]::Zero) Start-Sleep -Milliseconds 80 [WinEnum]::keybd_event(0x1B, 0, 2, [UIntPtr]::Zero) Start-Sleep -Milliseconds 800 Write-Host "=== 按 Esc 后 ===" Show-Windows $wheel2 = $script:Wins | Where-Object { $_.Title -like '*Wheel*' } if ($wheel2 -and $wheel2.Visible) { throw "Esc 后轮盘仍可见" } Write-Host "PASS: 轮盘已关闭" Write-Host "SMOKE OK" } finally { if (-not $proc.HasExited) { Stop-Process -Id $proc.Id -Force } }