使用PowerShell实现Windows已打开程序切换的代码修复请求
修复PowerShell窗口切换失效问题
原代码仅输出循环提示但无法实现窗口切换,核心问题在于废弃API使用、变量作用域错误、未处理最小化窗口三类问题。以下是修复后的完整代码:
Add-Type @" using System; using System.Text; using System.Runtime.InteropServices; public class WinAPI { public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] public static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); } "@ function Get-OpenWindows { $windows = New-Object System.Collections.Generic.List[IntPtr] $callback = [WinAPI+EnumWindowsProc]{ param($hWnd, $lParam) if ([WinAPI]::IsWindowVisible($hWnd)) { $buffer = New-Object System.Text.StringBuilder 256 [WinAPI]::GetWindowText($hWnd, $buffer, $buffer.Capacity) | Out-Null $title = $buffer.ToString() if ($title -ne "") { $windows.Add($hWnd) } } return $true } [WinAPI]::EnumWindows($callback, [IntPtr]::Zero) | Out-Null return $windows } # Settings $intervalMinutes = 5 $totalDurationMinutes = 30 $cycles = $totalDurationMinutes / $intervalMinutes # 恢复窗口参数:9表示还原最小化窗口 $restoreWindowFlag = 9 for ($i = 0; $i -lt $cycles; $i++) { Write-Host "Cycle $($i+1) starting..." $windows = Get-OpenWindows foreach ($hWnd in $windows) { # 先恢复最小化的窗口 [WinAPI]::ShowWindow($hWnd, $restoreWindowFlag) # 切换到目标窗口 $success = [WinAPI]::SetForegroundWindow($hWnd) if ($success) { Write-Host "成功切换到窗口句柄: $hWnd" } else { Write-Host "切换窗口句柄 $hWnd 失败" } Start-Sleep -Seconds 5 } Start-Sleep -Seconds ($intervalMinutes * 60) }
关键修改说明:
- 替换废弃API:移除已被系统弃用的
SwitchToThisWindow,改用官方推荐的SetForegroundWindow实现窗口激活,同时新增ShowWindow处理最小化窗口,确保窗口能正常显示。 - 修复变量作用域:原代码中用普通数组
$windows += $hWnd无法在脚本块内正确修改外部数组,改用List<IntPtr>的Add方法规避作用域问题,保证窗口句柄能被正确收集。 - 增加调试反馈:添加窗口切换成功/失败的提示信息,方便排查单窗口切换异常问题。
- 处理最小化场景:调用
ShowWindow传递参数9,自动还原最小化的窗口,确保SetForegroundWindow能正常激活目标窗口。
内容的提问来源于stack exchange,提问作者NottyHead




