diff --git a/src/main/capabilities/cv-vision.ts b/src/main/capabilities/cv-vision.ts index c80dfed..84ebc5d 100644 --- a/src/main/capabilities/cv-vision.ts +++ b/src/main/capabilities/cv-vision.ts @@ -26,9 +26,12 @@ function cvTarget(args: Record, nodeId: string): string { async function grabScreen(imagePath: string): Promise { fs.mkdirSync(path.dirname(imagePath), { recursive: true }); const psScript = [ + // 与点击脚本一致: 先声明 DPI 感知, 否则缩放非 100% 时 Bounds 是逻辑像素, 截屏只覆盖屏幕左上角 + "Add-Type -MemberDefinition '[DllImport(\"user32.dll\")] public static extern bool SetProcessDpiAwarenessContext(IntPtr value);' -Name RpaCvDpi -Namespace RpaCv | Out-Null;", + "try { [RpaCv.RpaCvDpi]::SetProcessDpiAwarenessContext([IntPtr](-4)) | Out-Null } catch {}", "Add-Type -AssemblyName System.Drawing | Out-Null;", "Add-Type -AssemblyName System.Windows.Forms | Out-Null;", - "$b = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds;", + "$b = [System.Windows.Forms.SystemInformation]::VirtualScreen;", "$bmp = New-Object System.Drawing.Bitmap($b.Width, $b.Height);", "$g = [System.Drawing.Graphics]::FromImage($bmp);", "$g.CopyFromScreen($b.X, $b.Y, 0, 0, $b.Size);", @@ -49,10 +52,15 @@ export async function locateTextOnScreen(target: string, nodeId: string): Promis const texts = result.texts ?? []; const keyword = target.trim(); const hit = texts.find(t => t.text && t.text.includes(keyword)); - try { fs.unlinkSync(shotPath); } catch {} if (!hit || !hit.box || hit.box.length < 4) { - throw new RuntimeError("cv_not_found", "屏幕上未找到目标文本:" + keyword, { nodeId, componentId: nodeId, recommendation: "确认目标文本在屏幕上可见且清晰" }); + // 找不到目标时保留截屏, 便于排查(截屏范围/遮挡/清晰度) + throw new RuntimeError("cv_not_found", "屏幕上未找到目标文本:" + keyword, { + nodeId, + componentId: nodeId, + recommendation: "确认目标文本在屏幕上可见且清晰;本次截屏已保留: " + shotPath + }); } + try { fs.unlinkSync(shotPath); } catch {} const xs = hit.box.map(p => p[0]); const ys = hit.box.map(p => p[1]); const cx = (Math.min(...xs) + Math.max(...xs)) / 2;