Files
isphere-ai-bridge/docs/n12r-internal-operator-minimal-retry-2026-07-09.md
2026-07-09 10:41:20 +08:00

8.1 KiB
Raw Blame History

N12R 内网操作员最小重做步骤

日期2026-07-09

适用对象:内网测试沙盒操作员。

目的:修正本次 N12R 返回包中 selected-window.json 缺失和 dump_uia 失败的问题,重新生成一个可被外网校验接受的 N12R 采集包。

1. 本次失败原因

本次返回包被外网校验拒收,核心原因是窗口句柄写错了。

日志中写成了:

$selectedHwnd = "<0x290E6E>"

这是错误写法。<HWND> 里的尖括号只是提示格式,实际填写时必须删掉。

正确写法是:

$selectedHwnd = "0x290E6E"

因为多了尖括号,后续窗口匹配失败:

selected hwnd not found in scan result: <0x290E6E>

所以:

  1. windows/selected-window.json 没有生成。
  2. dump_uia 使用了无效 hwnd。
  3. uia/dump-uia-main.json 返回 WINDOW_NOT_FOUND

2. 重做前确认

在内网测试沙盒中打开 PowerShell进入仓库根目录

cd E:\isphere-ai-bridge

确认 iSphere / IMPlatformClient 已经人工登录,并且主窗口可见、没有最小化。

不要执行以下动作:

搜索联系人
打开会话
发送消息
发送文件
接收/下载文件
自动登录
注入
hook
读取内存
绕过安防

3. 推荐做法:重新运行 scan_windows

窗口句柄可能已经变化,所以推荐先重新扫描窗口。

如果沿用原采集编号:

$captureId = "2026-07-08-internal-sandbox-a"
$captureRoot = "runs\internal-sandbox-live-capture\$captureId"
$helper = Resolve-Path -LiteralPath "runs\win-helper\ISphereWinHelper.exe"

重新扫描可见窗口:

@{
  protocol = "isphere.helper.v1"
  request_id = "n12r-scan-windows-retry"
  op = "scan_windows"
  timeout_ms = 5000
  args = @{ include_all_visible = $true }
} | ConvertTo-Json -Depth 8 -Compress |
  & $helper --json |
  Set-Content -Path "$captureRoot\windows\scan-windows.json" -Encoding UTF8

查看候选窗口:

Get-Content -Path "$captureRoot\windows\scan-windows.json" -Encoding UTF8 | ConvertFrom-Json |
  Select-Object -ExpandProperty data |
  Select-Object -ExpandProperty windows |
  Where-Object { $_.process_name -match "iSphere|IMPlatform|IMPP" -or $_.title -match "iSphere|IMPlatform|IMPP" } |
  Format-Table hwnd,pid,process_name,title,class_name,visible,score -AutoSize

从输出中选择 iSphere / IMPlatformClient 主窗口的 hwnd

示例中之前的候选值是:

0x290E6E

如果这次扫描输出变了,请使用新的 hwnd

4. 正确保存 selected-window.json

把下面命令中的 0x290E6E 改成你刚刚确认的真实窗口句柄。

注意:不要加尖括号。

正确:

$selectedHwnd = "0x290E6E"

错误:

$selectedHwnd = "<0x290E6E>"

保存所选窗口元数据:

$selectedHwnd = "0x290E6E"

$scanObj = Get-Content -Path "$captureRoot\windows\scan-windows.json" -Encoding UTF8 | ConvertFrom-Json
$selected = $scanObj.data.windows | Where-Object { $_.hwnd -eq $selectedHwnd } | Select-Object -First 1
if (-not $selected) { throw "selected hwnd not found in scan result: $selectedHwnd" }
$selected | ConvertTo-Json -Depth 8 | Set-Content -Path "$captureRoot\windows\selected-window.json" -Encoding UTF8

确认文件已经生成:

Test-Path -LiteralPath "$captureRoot\windows\selected-window.json"

期望输出:

True

5. 重新执行 dump_uia

@{
  protocol = "isphere.helper.v1"
  request_id = "n12r-dump-uia-main-retry"
  op = "dump_uia"
  timeout_ms = 15000
  args = @{
    hwnd = $selectedHwnd
    max_depth = 8
    include_text = $true
    max_children = 100
  }
} | ConvertTo-Json -Depth 12 -Compress |
  & $helper --json |
  Set-Content -Path "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8

检查结果是否成功:

$dump = Get-Content "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 | ConvertFrom-Json
$dump.ok
$dump.error

期望:

True

并且 $dump.error 应为空或为 null

如果仍然是 WINDOW_NOT_FOUND,说明窗口句柄已经失效。请回到第 3 步重新扫描并选择新的 hwnd。

6. 重新创建脱敏副本

Copy-Item -LiteralPath "$captureRoot\uia\dump-uia-main.json" -Destination "$captureRoot\uia\dump-uia-main-redacted.json" -Force

然后人工打开:

$captureRoot\uia\dump-uia-main-redacted.json

脱敏可见敏感文本,例如:

人员姓名
手机号
邮箱
消息文本
联系人名称
敏感业务标题
类似 token / 密码 / cookie 的字符串

尽量保留这些结构字段:

control_type
automation_id
class_name
framework_id
bounds
is_enabled
is_offscreen
children

7. 修正 source-notes.txt

打开:

$captureRoot\metadata\source-notes.txt

把这些字段从 是/否 改成真实值:

iSphere manually logged in: 是
client opened before capture: 是
main window visible: 是

如果真实情况不是“是”,不要继续打包,先重新完成对应动作。

8. 修正 operator-notes.txt

打开:

$captureRoot\notes\operator-notes.txt

不要保留 <...> 示例内容。请改成真实说明。

示例:

打开的客户端: iSphere / IMPlatformClient
登录方式: 人工正常公司流程
是否使用 MFA/SSO: 是,不包含任何秘密
所选窗口 hwnd: 0x290E6E
选择该窗口的原因: process_name 为 IMPlatformClient标题为国网甘肃省电力公司visible=Truescore=65
已做脱敏: 已检查 dump-uia-main-redacted.json移除可见敏感文本
采集问题: 首次把 hwnd 写成 <0x290E6E> 导致失败,本次已修正为 0x290E6E 后重新采集
forbidden actions performed: no

9. 复制出去前必须验证

运行必需文件检查:

$required = @(
  "$captureRoot\metadata\source-notes.txt",
  "$captureRoot\helper\version.json",
  "$captureRoot\helper\self-check.json",
  "$captureRoot\windows\scan-windows.json",
  "$captureRoot\windows\selected-window.json",
  "$captureRoot\uia\dump-uia-main.json",
  "$captureRoot\uia\dump-uia-main-redacted.json",
  "$captureRoot\notes\operator-notes.txt"
)
foreach ($path in $required) {
  if (-not (Test-Path -LiteralPath $path)) { throw "missing required file: $path" }
}
"N12R retry package files present: $captureRoot" | Tee-Object -FilePath "$captureRoot\metadata\verification-summary.txt"

运行 JSON 解析检查:

Get-Content "$captureRoot\helper\version.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null
Get-Content "$captureRoot\helper\self-check.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null
Get-Content "$captureRoot\windows\scan-windows.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null
Get-Content "$captureRoot\windows\selected-window.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null
Get-Content "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null
Get-Content "$captureRoot\uia\dump-uia-main-redacted.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null

检查 UIA dump 必须是成功:

$dump = Get-Content "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 | ConvertFrom-Json
if (-not $dump.ok) { throw "dump_uia failed: $($dump.error | ConvertTo-Json -Depth 8 -Compress)" }

10. 重新压缩返回

Compress-Archive -LiteralPath $captureRoot -DestinationPath "$captureRoot.zip" -Force

把新的 zip 或目录返回给外网协调环境。

返回时请同时说明:

N12R 重采/补采包已准备好。
路径: runs/internal-sandbox-live-capture/2026-07-08-internal-sandbox-a/
人工 iSphere 登录: 是
采集期间主窗口可见: 是
forbidden actions performed: no
本次已修正 hwnd不再包含尖括号selected-window.json 已生成dump_uia ok=true

11. 外网收到后如何判断

外网协调环境会重新运行:

powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\validate-n12r-return-package.ps1 `
  -PackageRoot <返回包目录> `
  -ReportPath <包外报告路径>

只有 validator 输出:

Decision: ACCEPT

才能进入 N13 selector 设计。