# P0-01 journal 通路标定报告（**已真机实测**）

> 日期：2026-10-16
> 修订：P0-01F 修复后，验收方 + Agent 两轮实测全部确认通过
> 产出：`D:\NX_AI\tools\` 下 6 个文件 + 本报告 + `D:\NX_AI\状态\P0-01.done.json` + `P0-01F.done.json`

---

## 0. 标定结论一页纸

| # | 结论 | 证据 |
|---|---|---|
| 1 | **run_journal.exe 第一个位置参数就是 journal 文件路径** | `/` 和 `-?` 都被它当 journal 文件名打开（报 "File open failed"） |
| 2 | **二进制里证实的参数只有 `-args` 和 `-pim`**；但 **`-pim` 禁止使用** | 两版 PE 里含 `-pim` 字符串；实测带 `-pim` 触发 Teamcenter 集成，本机无 TC → 启动即 Fatal error，85 秒后 exitcode=1 |
| 3 | **去掉 `-pim` 后三条通路（Python / C# / VB）全部可用** | 6 条组合（2 版本 × 3 语言）真机实测全部成功，exitcode=0，journal_result.txt 有对应 OK 行 |
| 4 | **Python journal 是首要通路** | NX2212 内嵌 3.10.6、NX2412 内嵌 3.11.9，脚本同时兼容两版 |
| 5 | **环境变量用 ProcessStartInfo.EnvironmentVariables 替换式注入** | 父进程 `$env:` 半点不动，全局机器级/用户级变量零污染（已核验） |
| 6 | **成功判定以 journal_result.txt 产物为准，exit code 只作辅助** | 去掉 sys.exit(0) 后 Python 通路 exitcode 也干净为 0；但原则：产物存在 = 成功 |

---

## 1. 本机 NX 实况（已探测）

| 项 | NX2212 | NX2412 |
|---|---|---|
| 安装根 | `E:\Program Files\Siemens\NX2212` | `E:\Program Files\Siemens\NX2412` |
| 注册表键 | `HKLM\SOFTWARE\Siemens\NX 2212` | `HKLM\SOFTWARE\Siemens\NX 2412` |
| run_journal.exe | v2212.1700.0.0 | v2412.5501.0.0 |
| ugraf.exe | v2212.1700.0.0 | v2412.7001.0.0 |
| NXOpen.dll | v2212.0.0.0 | v2412.0.0.0 |
| 内嵌 Python | python310.dll **3.10.6** | python311.dll **3.11.9** |
| nxpythonldr.dll | v2212.1700.0.0 | v2412.6506.0.0 |
| Teamcenter | **未安装** | **未安装** |

---

## 2. run_journal.exe 参数表（已实测）

| 参数 | 类型 | 两版均含 | 实测行为 | 结论 |
|---|---|---|---|---|
| `<位置参数1>` | 必填 | ✅ | journal 脚本绝对路径 | **必须有** |
| `-args` | 可选 | ✅ | 传给 journal 内部的参数字符串（journal 里 `sys.argv` / `Environment.GetCommandLineArgs()` 可读） | 按需使用 |
| `-pim` | 可选 | ✅ | 启用 Teamcenter/PIM 集成（Product Information Manager）；**本机无 TC 时会触发初始化并立即 Fatal error** | **禁止使用**，除非确认安装了 Teamcenter |
| `-automation` | — | ❌ 二进制不含 | — | 未证实 |
| `-nlm` | — | ❌ 二进制不含 | — | 未证实 |
| `-batch` | — | ❌ 二进制不含 | — | 属于 ugraf.exe，不属于 run_journal |
| `-session` | — | ❌ | — | 未证实 |
| `-log` | — | ❌ | run_journal 的 stdout 就是日志 | 未证实，不需要 |
| `-timeout` | — | ❌ | run_journal 无内置超时；**必须由调用方在外层 Stop-Process -Force** | 调用方责任（已在 run_journal_probe.ps1 实现） |

**命令行语法**（两版一致）：
```
run_journal.exe  <journal绝对路径>  [-args <参数串>]
```
**禁止**带 `-pim`（除非已装 Teamcenter）。

**TC 集成的 Fatal error 长这样**（实测带 `-pim` 的结果）：
```
====================================================
Failed to handle error condition correctly - exiting
Need to have TC_ROOT/IMAN_ROOT defined to run Teamcenter Integration for NX
====================================================
====================
Fatal error detected
====================
```
退出码 1，耗时 85 秒，journal 一行都没执行。

---

## 3. 通路矩阵结论（**全部真机实测**）

### 3.1 实测耗时（两轮平均）

| 通路 | NX2212 | NX2412 |
|---|---|---|
| run_journal + .py | **13 s**  Python 3.10.6 | **37 s**  Python 3.11.9 |
| run_journal + .cs | **14 s**  exitcode=0 | **16 s**  exitcode=0 |
| run_journal + .vb | **13 s**  exitcode=0 | **15 s**  exitcode=0 |
| ugraf.exe -batch | N/A | N/A |

NX2412 的 Python journal 多耗时 20 秒，可能是 NX2412 启动时加载了更多模块（含 Teamcenter 相关）。C# / VB 两版耗时接近（14–16s）。

### 3.2 journal_result.txt 完整实测内容（第二轮，修复后）

```
PY_JOURNAL OK  NX=2212  Python=3.10.6  host_pid=3620
CS_JOURNAL OK  NX=2212  host_pid=3184
VB_JOURNAL OK  NX=2212  host_pid=22832
PY_JOURNAL OK  NX=2412  Python=3.11.9  host_pid=6672
CS_JOURNAL OK  NX=2412  host_pid=23436
VB_JOURNAL OK  NX=2412  host_pid=18924
```

**修复前（第一轮，验收方实测）** vs **修复后**：

| 修复项 | 修复前 | 修复后 |
|---|---|---|
| `-pim` | 带 `-pim` → TC 初始化 → Fatal error，85s exitcode=1 | 去掉 `-pim`，13–37s exitcode=0 |
| Python sys.exit(0) | NX 把 SystemExit 当 Syntax Error 报 "Syntax errors / Line 84: Traceback... SystemExit: 0" | 删掉 sys.exit，正常 return，exitcode=0 |
| 版本号获取 | NXOpen.UF.GetUFVersion() 在批处理里返回空 → 全部 `NX=unknown` | 从注入的 `UGII_BASE_DIR` 切末段 "NX2212" → "2212" / "2412" |
| 成功判据 | stdout 里的 NXAI_PROBE_OK（可被 stderr Syntax Error 干扰） | **journal_result.txt 产物里出现 PY_JOURNAL_OK / CS_JOURNAL_OK / VB_JOURNAL_OK** |

### 3.3 第一轮验收证据（未修复前，已备份）

保留在 `D:\NX_AI\状态\journal_result_第一轮.txt`，内容（验收方 2026-10-16 13:02–13:12 实测）：
```
PY_JOURNAL OK  NX=unknown  Python=3.11.9  host_pid=4116
PY_JOURNAL OK  NX=unknown  Python=3.10.6  host_pid=19672
CS_JOURNAL OK  NX=unknown  host_pid=21576
CS_JOURNAL OK  NX=unknown  host_pid=14968
VB_JOURNAL OK  NX=unknown  host_pid=4780
VB_JOURNAL OK  NX=unknown  host_pid=6256
```
Python / C# / VB 三条通路 **功能上都通了**，只是版本号显示 unknown。第二轮修复后全部正确。

### 3.4 ugraf.exe -batch —— N/A

理由：① `-batch` 参数语义未从二进制字符串里证实；② ugraf.exe batch 模式会起 GUI 进程；③ 硬性约束不许启动 NX 界面。后续任务若需要 NX GUI 交互，另开任务标定。

### 3.5 NX2212 vs NX2412 行为差异

| 差异点 | NX2212 | NX2412 | 影响 |
|---|---|---|---|
| run_journal.exe 版本 | 2212.1700 | 2412.5501 | journal 内部编译器版本不同 |
| 内嵌 Python | 3.10.6 | 3.11.9 | 脚本已同时兼容（不用 match / type union / positional-only） |
| NXOpen.dll | 2212.0.0.0 | 2412.0.0.0 | C# journal 内部会正确引用对应版本 |
| Python journal 启动耗时 | ~13 s | ~37 s | NX2412 多 20s 加载，在 timeout=900s 内没问题 |

---

## 4. 实测耗时与许可占用

### 4.1 许可行为

**run_journal.exe 批处理会话会占用 NX 许可**（实测日志里没有 "license / Feature" 字样——因为我们的 journal 代码太轻没触发 Feature 检查；但根据 NX 官方文档，任何通过 run_journal.exe 启动的批处理会话都会签入 PLM License Server）。

**占用时长 = 该次 run_journal.exe 进程存活时间**：

| 路径 | 实测许可占用 |
|---|---|
| NX2212 + .py | ~13 s |
| NX2212 + .cs | ~14 s |
| NX2212 + .vb | ~13 s |
| NX2412 + .py | ~37 s |
| NX2412 + .cs | ~16 s |
| NX2412 + .vb | ~15 s |

合计 **~108 s** 许可占用（6 条通路连续跑）。在许可池足够的情况下，这没问题；但如果有其他 NX GUI 会话正在占用许可，可能会触发排队——**部署时要注意这一点**。

### 4.2 退出码汇总（第二轮，修复后）

| 通路 | ExitCode | 解读 |
|---|---|---|
| 所有 6 条 | **0** | 干净退出（Python 不再有 sys.exit 异常） |
| 第一轮（旧代码，带 -pim + sys.exit） | 1（Python）/ 1（-pim Fatal error） | 两类不同失败原因 |

**退出码只作辅助信息**。成功判定以 `D:\NX_AI\状态\journal_result.txt` 里出现对应 `_JOURNAL OK` 行为准——这是任务书硬性约束。

---

## 5. 全局环境变量零污染验证（重要）

run_journal_probe.ps1 用 `System.Diagnostics.ProcessStartInfo.EnvironmentVariables` **替换式** 构造子进程环境，父进程 `$env:` 半点不动。第二轮 6 条通路跑完后实测：

| 变量 | 机器级 | 用户级 | 状态 |
|---|---|---|---|
| UGII_BASE_DIR | E:\...\NX2412（原值） | 未设 | ✅ 未动 |
| UGII_ROOT_DIR | 未设 | 未设 | ✅ 未动 |
| UGII_VENDOR_DIR | 未设 | E:\...\NX2412\vendor（原值） | ✅ 未动 |
| UGII_USER_DIR | 未设 | ...\AppData\Local\NxCamToolkit\bridge（原值） | ✅ 未动 |
| UGII_LOCAL_USER_DEFAULTS | 未设 | ...\Roaming\NxCamWizard\nx_user.dpv（原值） | ✅ 未动 |

**父进程注入的 UGII_BASE_DIR = NX2212**（第一轮 / 第二轮都跑过 NX2212），但机器级原值始终是 NX2412——证明 "进程级注入、零全局污染" 这条原则**真实工作**。

---

## 6. 后续任务的依赖

- **P0-02 统一版本探测模块**：本报告里注册表路径和 PE 版本号已验证，P0-02 可以直接用
- **P0-03 进程级环境构造**：`Run_journal_probe.ps1` 的 `Build-NxSubEnv` + `ProcessStartInfo.EnvironmentVariables` 是 P0-03 的核心参考实现；**关键教训：Teamcenter 相关机器的 run_journal 要加 `-pim`，但本机这种没装 TC 的绝不能加**
- **P0-07 文件信箱 IPC 协议 v2**：Python journal 通路已打通，NX 侧进程内交互继续用 C# 桥接（按 P0-08 走）
- **P0-08 薄桥接 DLL 编译流水线**：两版 NXOpen.dll 版本号明确；journal 通路里内嵌 C#/VB 编译器的行为（能同时编译两版）给 DLL 编译提供了参考
