You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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

火山引擎 最新活动