From c93543be1c8b8987e77d252539d64c7d7cff91e7 Mon Sep 17 00:00:00 2001 From: yu <191972707@qq.com> Date: Mon, 2 Nov 2026 17:46:14 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=20CV=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E9=87=8D=E5=A4=8D=E6=B3=A8=E5=86=8C=E4=B8=8E=E9=9D=9E?= =?UTF-8?q?=E6=B3=95=E5=8D=95=E8=A1=8C=20here-string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remaining-core.ts 曾重复注册 CV_GetText/SetText/MouseHover/MouseClick 并覆盖 cv-vision.ts 的实现 - 其中 CV_MouseClick/MouseHover 内联的 Add-Type @'...'@ 单行 here-string 是非法语法(@' 后必须紧跟换行), 必然解析失败报 CLIXML 错误 - 移除重复注册, CV 组件统一走 cv-vision.ts 的 -MemberDefinition 实现 - 顺手修复 Image_Move 系列同款单行 here-string bug(改为 -MemberDefinition) --- src/main/capabilities/remaining-core.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/capabilities/remaining-core.ts b/src/main/capabilities/remaining-core.ts index 6ea1a1d..368de56 100644 --- a/src/main/capabilities/remaining-core.ts +++ b/src/main/capabilities/remaining-core.ts @@ -5,7 +5,6 @@ import { runFlow } from "../engine/runtime"; import { RuntimeError, type CapabilityHandler, type RunContext } from "../engine/types"; import { powershell, psString } from "./desktop"; import { findImage } from "./vision"; -import { locateTextOnScreen } from "./cv-vision"; function text(args: Record, keys: string[], fallback = ""): string { for (const key of keys) { const value = args[key]; if (value !== undefined && value !== null && value !== "") return String(value); } @@ -176,7 +175,8 @@ for (const id of ["Image_Location", "Image_Location_V1"]) register(id, async (_c for (const id of ["Image_Wait", "Image_Wait_V1"]) register(id, async (_ctx, node, args) => findOnScreen(args, node, num(args, ["timeout", "time_out"], 10))); for (const id of ["Image_Move", "Image_Move_V1", "Image_Move_V2"]) register(id, async (_ctx, node, args) => { const hit = await findOnScreen(args, node); const x = Math.round(hit.x + hit.width / 2); const y = Math.round(hit.y + hit.height / 2); - await powershell(`Add-Type @'using System;using System.Runtime.InteropServices;public static class ImageMoveUser32{[DllImport("user32.dll")]public static extern bool SetCursorPos(int x,int y)}'@;[ImageMoveUser32]::SetCursorPos(${x},${y})`); + // 注意: PowerShell here-string(@'...'@)的 @' 后必须紧跟换行, 不能拼成单行; 用 -MemberDefinition 内联声明避开该语法 + await powershell("Add-Type -MemberDefinition '[DllImport(\"user32.dll\")] public static extern bool SetCursorPos(int X, int Y);' -Name RpaImageMoveInput -Namespace RpaImageMove | Out-Null; [RpaImageMove.RpaImageMoveInput]::SetCursorPos(" + x + "," + y + ")"); return { ...hit, x, y }; }); register("Image_Base64Encode", async (_ctx, _node, args) => fs.readFileSync(path.resolve(text(args, ["path", "image"]))).toString("base64")); @@ -200,15 +200,10 @@ register("logic_control_if_ai_vision", async (ctx, node, args) => { const screenshot = path.join(ctx.evidenceDir, `ai-vision-${Date.now()}.png`); await captureScreen(screenshot); return { image: screenshot, prompt: text(args, ["input_data", "prompt", "condition"], "描述屏幕内容并判断条件是否成立"), matched: true }; }); -register("CV_GetText", async (_ctx, node, args) => { const target = required(text(args, ["cvSelector", "target", "text"]), "CV目标", node); return (await locateTextOnScreen(target, node.id)).text; }); -for (const id of ["CV_SetText", "CV_MouseHover", "CV_MouseClick"] as const) register(id, async (_ctx, node, args) => { - const target = required(text(args, ["cvSelector", "target", "text"]), "CV目标", node); const hit = await locateTextOnScreen(target, node.id); - const x = Math.round(hit.cx + num(args, ["offsetX"], 0)); const y = Math.round(hit.cy + num(args, ["offsetY"], 0)); - if (id === "CV_SetText") await powershell(`Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait("^a");[System.Windows.Forms.SendKeys]::SendWait(${psString(text(args, ["text", "value"]))})`); - else if (id === "CV_MouseClick") await powershell(`Add-Type @'using System;using System.Runtime.InteropServices;public static class CvClickUser32{[DllImport("user32.dll")]public static extern bool SetCursorPos(int x,int y);[DllImport("user32.dll")]public static extern void mouse_event(uint f,uint x,uint y,uint d,UIntPtr e)}'@;[CvClickUser32]::SetCursorPos(${x},${y});Start-Sleep -Milliseconds 100;[CvClickUser32]::mouse_event(2,0,0,0,[UIntPtr]::Zero);[CvClickUser32]::mouse_event(4,0,0,0,[UIntPtr]::Zero)`); - else await powershell(`Add-Type @'using System;using System.Runtime.InteropServices;public static class CvHoverUser32{[DllImport("user32.dll")]public static extern bool SetCursorPos(int x,int y)}'@;[CvHoverUser32]::SetCursorPos(${x},${y})`); - return { ...hit, x, y }; -}); +// CV_GetText / CV_SetText / CV_MouseHover / CV_MouseClick 统一由 cv-vision.ts 注册: +// 此处曾重复注册并覆盖 cv-vision 的实现,其中内联 here-string(@'...'@ 单行)是 +// 非法 PowerShell 语法,导致 CV_MouseClick/CV_MouseHover 必然解析失败(报 CLIXML 错误)。 +// 如需调整 CV 行为请修改 cv-vision.ts,不要在此重复注册。 async function xunfeiRequest(args: Record, operation: string, payload: Record) { const endpoint = text(args, ["endpoint"]); if (!endpoint) throw new RuntimeError("validation_error", "需要配置讯飞 API endpoint");