diff --git a/src/main/capabilities/desktop.ts b/src/main/capabilities/desktop.ts index b0a96d9..1f51317 100644 --- a/src/main/capabilities/desktop.ts +++ b/src/main/capabilities/desktop.ts @@ -167,13 +167,18 @@ const mouseRoll: CapabilityHandler = async (_ctx, node, args) => { return amount; }; -/** 把匹配标题的窗口带到前台(Alt trick + AttachThreadInput 兜底);拼在 USER32 之后使用 */ +/** 把匹配标题的窗口带到前台;多招式依次兜底(应用点击「运行」后自身是前台, + * Windows 前台锁定策略会拒绝普通 SetForegroundWindow,最小化再恢复可绕过) */ function activateWindowScript(selector: string): string { return `$p = Get-Process | Where-Object { $_.MainWindowTitle -and $_.MainWindowTitle -like ${psString(`*${selector}*`)} } | Select-Object -First 1 if (-not $p) { throw '找不到窗口:${selector.replace(/'/g, "''")}' } -Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr h, int cmd); [DllImport("user32.dll")] public static extern bool IsIconic(IntPtr h); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h); [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr pid); [DllImport("user32.dll")] public static extern bool AttachThreadInput(uint a, uint b, bool attach); [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId();' -Name RpaFocus2 -Namespace WinRpaFocus2 | Out-Null +Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr h, int cmd); [DllImport("user32.dll")] public static extern bool IsIconic(IntPtr h); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h); [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr pid); [DllImport("user32.dll")] public static extern bool AttachThreadInput(uint a, uint b, bool attach); [DllImport("user32.dll")] public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId();' -Name RpaFocus2 -Namespace WinRpaFocus2 | Out-Null $h = $p.MainWindowHandle -if ([WinRpaFocus2.RpaFocus2]::IsIconic($h)) { [void][WinRpaFocus2.RpaFocus2]::ShowWindow($h, 9) } +if ([WinRpaFocus2.RpaFocus2]::IsIconic($h)) { [void][WinRpaFocus2.RpaFocus2]::ShowWindow($h, 9); Start-Sleep -Milliseconds 150 } +if ([WinRpaFocus2.RpaFocus2]::GetForegroundWindow() -ne $h) { + [void][WinRpaFocus2.RpaFocus2]::SwitchToThisWindow($h, $true) + Start-Sleep -Milliseconds 150 +} if ([WinRpaFocus2.RpaFocus2]::GetForegroundWindow() -ne $h) { [void][WinRpaFocus2.RpaFocus2]::keybd_event(0x12, 0, 0, [UIntPtr]::Zero) [void][WinRpaFocus2.RpaFocus2]::SetForegroundWindow($h) @@ -187,7 +192,13 @@ if ([WinRpaFocus2.RpaFocus2]::GetForegroundWindow() -ne $h) { try { [void][WinRpaFocus2.RpaFocus2]::SetForegroundWindow($h) } finally { if ($attached) { [void][WinRpaFocus2.RpaFocus2]::AttachThreadInput($thisThread, $fgThread, $false) } } Start-Sleep -Milliseconds 200 } -if ([WinRpaFocus2.RpaFocus2]::GetForegroundWindow() -ne $h) { throw '前台切换失败' }`; +if ([WinRpaFocus2.RpaFocus2]::GetForegroundWindow() -ne $h) { + [void][WinRpaFocus2.RpaFocus2]::ShowWindow($h, 6) + Start-Sleep -Milliseconds 150 + [void][WinRpaFocus2.RpaFocus2]::ShowWindow($h, 9) + Start-Sleep -Milliseconds 300 +} +if ([WinRpaFocus2.RpaFocus2]::GetForegroundWindow() -ne $h) { throw '无法把窗口带到前台,请确认窗口未被关闭或全屏占用' }`; } const setActiveWindow: CapabilityHandler = async (_ctx, node, args) => {