PRA-only-demo/contrib/windows-runner-actuate/PORTING-MAP.md

5.6 KiB
Raw Blame History

PowerShell → C# 移植对照表(RPA 桌面驱动 → windows-runner actuate)

来源:packages/rpa-core/src/driver/windows/windows-driver.ts(269 行,内嵌 PowerShell) 目标:对面 code/backend/services/windows-runner/native/(原型见本目录 native/)

一、原语级映射

RPA 侧 PowerShell 原语 用途(驱动行号) C# 等价物(原型落点) 语义保真要点
SetCursorPos(x,y) moveTo / click / drag / moveSmooth(L142,150,158,173) NativeInput.SetCursorPos 物理像素;进程入口声明 Per-Monitor V2 DPI(对应 PS 每脚本的 SetProcessDpiAwarenessContext(-4),一次声明进程级生效)
mouse_event(flags,0,0,data,0) down/up click / drag(L150,158) SendInput(MOUSEEVENTF_LEFTDOWN=0x0002 / LEFTUP=0x0004 / RIGHTDOWN=0x0008 / RIGHTUP=0x0010) SendInput 是 mouse_event 的现代等价;标志位一一对应。双击=repeats 2,settleMs 逐次保留
mouse_event(0x0800,...,amount) scroll(L161) SendInput + MOUSEEVENTF_WHEEL,mouseData=有符号 delta 负值向下滚,unchecked((uint)amount) 保持位型一致
GetCursorPos + JS mousePath 插值 moveSmooth(L163-174) ActuateService.SmoothMovePath(公式逐行移植) 缓入缓出二次曲线 + 垂直抖动 sin(i*12.9898)*43758.5453 % 1;stepCount=clamp(distance/12, 6, 50);delay=clamp(1500/speed, 4, 80)ms。JS 与 C# 的 % 对负数同为保号语义,公式无漂移
Set-Clipboard + SendWait('^v') keyboard clipboard 模式(L183) Clipboard.SetDataObject(text, true) + SendKeys.SendWait("^v") 120ms 间隙保留;STA 已由对面 [STAThread] 保证
SendWait($c) 逐字符循环 keyboard manual 模式(L188) 逐字符 SendKeys.SendWait(Escape(ch)) + Thread.Sleep(intervalMs) intervalMs 逐字符保留
SendWait(escaped) 整段 keyboard 默认模式(L192) SendKeys.SendWait(escaped) sendKeysEscape 字符集 +^%~(){}[] → {+} 等花括号转义,逐字符同规则移植(ActuateService.EscapeSendKeys)
activateWindowScript 抢前台五招兜底 focus(L73-105,键盘与激活共用) NativeInput.FocusChain(逐行移植) 顺序与睡眠严格保留:①IsIconic→SW_RESTORE(9)+150ms ②SwitchToThisWindow+150ms ③ALT(0x12 down/up)+SetForegroundWindow+200ms ④AttachThreadInput 对线程+SetForegroundWindow+200ms ⑤SW_MINIMIZE(6)+150ms→SW_RESTORE(9)+300ms ⑥仍失败→稳定错误码 focus_failed(PS 版走 RPA_ERROR:: stdout 通道)
`Get-Process MainWindowTitle -like title` 窗口查找(L60-68 等) Win32 EnumWindows + 精确标题 + PID 回查进程名 + Session 校验(复用对面 observe 的 SelectWindow 模式)
GetWindowRect + JSON 输出 windowObject / foregroundPosition(L66,213) NativeWindows.GetWindowRect(对面已有,直接复用) RECT right/bottom → width/height 换算保持
ShowWindow(h, 3/6/9/cmd) activate/maximize / setState / 五招内部(L203,224) NativeInput.ShowWindow 命令值原样透传
SetWindowPos(h,0,x,y,w,h,4) setSize / setPos(L227,231) NativeInput.SetWindowPos flags=4(SWP_NOZORDER)原样保留;尺寸>0 校验保留(L230)
Process.CloseMainWindow() close(L221) PostMessage(h, WM_CLOSE=0x0010) 等价语义(礼貌关闭,不杀进程)
System.Windows.Forms.Screen.PrimaryScreen.Bounds screen.size(L246) 不移植——observe op 的 CoordinateSpace 已携带窗口矩形+DPI 避免重复采集

二、必须知道的三处语义差异(宿主适配层负责弥合)

  1. 窗口匹配从模糊变精确。PS 版 Get-Process -like *title* 是包含匹配;对面安全政策要求 WindowTitle 与 AllowedWindows 精确相等(模糊匹配会把同名网页/提示框误当目标)。弥合方式:TS 宿主适配器先用 observe 解析出精确标题与进程名,再发起 actuate 请求——RPA 能力层(window.findByTitle)语义不变,只是解析下沉到宿主。
  2. 进程模型从"每命令一进程"变"单请求单响应"。PS 版每个原语起一个 powershell.exe;C# 版一次请求一次响应、宿主超时杀进程(对面现行架构)。RPA 流程里相邻原语本来也无状态依赖(除句柄传递,改由标题精确匹配承担),语义等价。注意:宿主超时必须覆盖 moveSmooth 最坏情况(约 4s)+ 两次证据截图。
  3. 副作用证据从无到有。PS 版动作无留痕;C# 版按对面证据体系在动作前后各截一张目标窗口 PNG(PrintWindow,SHA-256 落盘,默认 secret)——这是对面 capability-gateway 审计链要求的,属于增强而非等价项。

三、稳定错误码映射(PS 侧 → C# 侧)

PS 侧失败 C# actuate 稳定错误码
找不到窗口:<title>(throw/RPA_ERROR) window_not_found(无候选)/ window_ambiguous(多候选,对面已有语义)/ window_not_allowed(不在白名单)
无法把窗口带到前台…(五招全失败) focus_failed
输入注入 Win32 失败 input_failed
证据截图失败/空白 capture_unavailable(沿用对面现有码)
政策校验失败 policy_invalid / desktop_session_mismatch(沿用对面现有码)

四、开关映射:mouse_event → SendInput 标志位

mouse_event flag SendInput MOUSEEVENTF 用途
0x0002 LEFTDOWN 左键按下
0x0004 LEFTUP 左键抬起
0x0008 RIGHTDOWN 右键按下
0x0010 RIGHTUP 右键抬起
0x0800 WHEEL 滚轮(data=delta,120 的倍数)