From f20b8ca6cd7f237dc542052713f4bdfcf7e5d8de Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期五, 09 十月 2026 13:47:50 +0800
Subject: [PATCH] 文件探查脚本改为找 .pcj 工步方案并打印逐工步内容

---
 scripts/j22-introspect-files.ps1 |   38 ++++++++++++++++++++++++++++++++++----
 1 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/scripts/j22-introspect-files.ps1 b/scripts/j22-introspect-files.ps1
index b47c694..6f5bb9e 100644
--- a/scripts/j22-introspect-files.ps1
+++ b/scripts/j22-introspect-files.ps1
@@ -2,8 +2,11 @@
   22 所上位机文件侧只读探查:工步方案(含可能的工步名称)在不在软件目录的文件里。
 
   为什么走文件侧:该机 SQL Server 的 5141 个用户库**全部**是 DB_<时间> 测试库、其他库 0 个,
-  所以工步方案不可能在库里。上一轮现场已在运行目录见到 VariableMap.xml、UnitConvert.xml、
-  DeviceConfiguration.xml、TaskModel.xml 等文件,另有遗留的 .sto 工步方案(gzip 压缩的 XML)。
+  所以工步方案不可能在库里。
+
+  方案文件是 `.pcj`(2026-10-09 现场确认):`SysSchedule` 格式的 XML、**没有压缩**,声明 utf-8,
+  每个工步一条 `<Step>`,带 `CtrlTypeName`(控制类型名)、`CtrlValue`(设定值)、`Limit`(截止条件)、
+  `GotoStep`(跳转),方案名在 `<ScheduleName>`。遗留的 `.sto`(gzip 压缩的 XML)也一并看。
 
   只读纪律:只列目录、只读文件内容;不写、不改厂商目录与文件;报告只写到本脚本所在目录。
 
@@ -21,6 +24,9 @@
     [int]$MaxFiles = 3,
     [int]$MaxHeadChars = 400,
     [int]$MaxNames = 25,
+    # 工步方案里打印前几个与后几个工步(中间省略),以及每个工步最多打印多少字。
+    [int]$StepPreview = 4,
+    [int]$MaxStepChars = 300,
     [string]$ReportFile = ''
 )
 
@@ -36,12 +42,18 @@
     [void]$report.Add($text)
 }
 
-# 方案文件的判据:.sto 一定是方案;名字里带 step/plan/task/recipe/scheme/program/工步/方案的也算。
+# 方案文件的判据:.pcj 是这台机器上软件的工步方案(SysSchedule XML,2026-10-09 现场确认),
+# .sto 是遗留方案(gzip 压缩的 XML);名字里带 step/plan/task/recipe/scheme/program/工步/方案的也算。
 # 其余文件(设备配置、单位换算表等)不看——它们存不下工步名称。
 function Test-PlanFile([string]$name) {
     $extension = [System.IO.Path]::GetExtension($name)
-    if ($extension -ieq '.sto') { return $true }
+    if ($extension -ieq '.pcj' -or $extension -ieq '.sto') { return $true }
     return $name -imatch '(step|plan|task|recipe|scheme|program|工步|方案)'
+}
+
+# 取一个 XML 标签的文本值;没有这个标签就返回空串。
+function Get-TagValue([string]$text, [string]$tag) {
+    return [regex]::Match($text, '<' + $tag + '>([^<]*)</' + $tag + '>').Groups[1].Value
 }
 
 # 读文件文本:gzip(.sto 是 gzip 压缩的 XML)自动解压;只读前若干字符,避免把大文件全读进来。
@@ -203,6 +215,24 @@
         $head = $text.Trim()
         if ($head.Length -gt $MaxHeadChars) { $head = $head.Substring(0, $MaxHeadChars) + ' …' }
         Say ('    文本开头:' + $head)
+
+        # 工步方案(.pcj / SysSchedule):逐工步的设定值、截止条件与跳转都在这里。
+        # 工步的"名称"通常就是每个工步的 CtrlTypeName(例如"恒流充电""搁置")——这一节就是要看它。
+        if ($text -match '<Steps>') {
+            $steps = [regex]::Matches($text, '(?s)<Step>.*?</Step>')
+            Say ('    方案名: ' + (Get-TagValue $text 'ScheduleName') + '    任务目录: ' + (Get-TagValue $text 'SchedulePath'))
+            Say ('    方案标题: ' + (Get-TagValue $text 'Caption') + '    说明: ' + (Get-TagValue $text 'Description') + '    最后修改: ' + (Get-TagValue $text 'LastUpdateTime'))
+            Say ('    工步数: ' + $steps.Count)
+            $index = 0
+            foreach ($step in $steps) {
+                $index++
+                # 只打印前几个与后几个:中间的省略,否则一个方案就能刷满屏。
+                if ($index -gt $StepPreview -and $index -le ($steps.Count - $StepPreview)) { continue }
+                $flat = $step.Value -replace '\s+', ' '
+                if ($flat.Length -gt $MaxStepChars) { $flat = $flat.Substring(0, $MaxStepChars) + ' …' }
+                Say ('      工步 ' + $index + ': ' + $flat)
+            }
+        }
     }
 
     Say ''

--
Gitblit v1.7.1