CAESAR II 与 AutoPIPE 二次开发教程3第一个可运行的批处理算例——从 GUI 跑通一次到命令行复现版本与事实声明AutoPIPE 的参数开关全表、命令形态、执行顺序规则、错误行为、官方TS-440.BAT示例逐条取自 Bentley 官方在线帮助 “Automated System Processing” 页可对照原文核对。CAESAR II 的Start Run/Batch Run语义来自多份公开技术资料的一致描述第三方转述级本篇按以官方 CAESAR II 用户手册为准表述不臆造其命令行参数。本篇涉及的TUTOR1是官方帮助提供的示例模型名文中的位号、温度、压力、节点号等均为示例性数据不代表任何标准规定。示例路径D:\StressDev\SYS-101\为约定路径实际以你的工程目录为准。一句话结论AutoPIPE 的无人值守执行形态是autopipe {filename} /h /s /m /r /a /f /i /g /o /t /v /n其中{filename}可带.ntlBatch 输入/.pxfAutoPLANT/.ciiCaesar 中立文件三种扩展名开关必须小写、至少以一个空格分隔、可以任意顺序书写但 AutoPIPE 一律按其固定顺序执行——所以我按物理顺序写了开关这个直觉是错的。〇、本篇要解决的认知问题Q1为什么先在 GUI 跑通一次是铁律不能跳过Q2AutoPIPE 的批处理命令长什么样参数开关各有几个、分别是什么意思Q3参数开关的书写顺序与执行顺序为什么不是一回事Q4/y与/z分别解决什么问题它们能替代真正的无人值守吗Q5CAESAR II 侧的Start Run与Batch Run分工是什么一、机制解析1.1 铁律 5先跑通一次再谈自动化“批处理跑完没报错不等于算对了”。这句话是整条铁律的核心。原因是无人值守场景下你失去了三条反馈没有对比基准——没人看着结果没法判断数值是否合理误差被放大——一个单位解释错误会在 200 个算例里重复 200 次成功但错误的产出会进入交付流程——比直接失败更危险。为什么这对你重要正确的开工顺序是——① 在 GUI 里手工建一个最小模型跑出你认可的、可复现的结果② 把它另存为文本NTL / 输入文件③ 用命令行重跑同一个模型比对结果与 GUI 是否一致④ 一致之后才允许把参数换成变量开始批量。1.2 AutoPIPE 的批处理命令形态官方 “Automated System Processing” 页给出的命令形态原样照录execute autopipe {filename} /h /s /m /r /a /f /i /g /o /t /v /n from the DOS prompt其中{filename}是 AutoPIPE 系统数据库名不带 DOS 扩展名如果省略filename所有开关都会被忽略。此外可以带扩展名指定输入类型autopipe {filename}.ntl ... # AutoPIPE Batch 文件 autopipe {filename}.pxf ... # AutoPLANT PXF 文件 autopipe {filename}.cii ... # Caesar CII 中立文件官方对自动化的定位写得很直白“the designer the opportunity to concentrate on modeling system databases during office hours, and then to run the desired analyses and create the result reports for each system overnight”——白天建模夜里跑分析出报告。这就是这条通道的价值主张。1.3 参数开关全表官方原文对照开关含义开关含义/a谐波分析/n法兰分析/c热瞬态分析/o生成输出报告/d建输入清单*.MDB/p把 NTL/PXF 转为 DAT/e1导出应力轴测*.DGN/r响应谱分析/e2导出应力轴测*.DWG/s静态分析/e3导出应力轴测*.DXF/t时程分析/e4导出应力轴测2D DGN/uEN1591 法兰分析/f力谱分析/v生成结果 MDB/g建输入清单/y自动应答所有消息提示/h吊架设计/z抑制 AutoPIPE GUI/i地震锚点位移分析/k导出为 NTL中立文件/l1EN1591 法兰 TXT 报告/l2EN1591 法兰 CSV 报告/l3EN1591 法兰 PDF 报告/l4EN1591 法兰 Word 报告两个高频组合最小可用/s /o——跑静态分析出输出报告。这是绝大多数批处理的起点含云图/清单/s /v /o——静态分析 结果 MDB 输出报告。/v生成的 MDB 是后续接数据面的原材料。1.4 语法铁律小写、空格分隔、按固定顺序执行官方原文要点直译参数开关必须以小写字母书写开关之间至少以一个空格分隔。可以在命令行上指定一个或多个开关且可以任意顺序列出。但是由于参数开关与其在 Analyze 与 Result 菜单中的热键字母相对应AutoPIPE 会按本页所示顺序执行它们与你指定的顺序无关。这条规则的机制解释开关本质是菜单动作的批处理代理。菜单动作之间存在依赖关系——例如生成输出报告/o依赖已经算过/s。如果真按用户书写顺序执行/o /s就会在没算之前去出报告。所以产品选了固定顺序这个安全设计你负责要不要做产品负责什么顺序做。还有两条容易踩的细节/e1~/e4一次只能用其中一个——官方明确in case of multiple isometrics switches, the last available switch is used多个时以最后一个为准。这意味着你不会得到两份轴测图只会得到最后那个格式的一份开关与 NTL 内嵌指令会互相影响——官方注明若指定了 Batch Input 文件且文件内已含相应的SOLVE与RESULT卡则命令行开关变得不必要反之若给了开关但文件缺相应SOLV卡中的选项该开关被忽略例MODE选项不存在时/m被忽略。这条被忽略规则是本篇最值钱的一条它意味着**我在命令行写了/m并不保证会做模态分析**——真正的开关权在 NTL 文件里的命令卡。排查为什么没跑模态时第一站是文件不是命令。1.5/y与/z它们不是无人值守开关官方对两者的定义很克制/y 自动应答所有消息提示/z 抑制 GUI。但同一页还写了一句必须同时读的话“During program execution, most of the screens that would normally appear if AutoPIPE was being executed interactively are displayed.If an error is encountered, the corresponding error message is displayed on the screen and program execution is halted until acknowledgment from the user is received.”执行期间大多数交互界面仍会显示遇到错误时会显示错误消息并暂停直到收到用户确认。把这两句放在一起读结论非常明确批处理无用户交互指的是不需要用户去点菜单、填对话框不是出错也能自己走下去。所以在做夜间批处理编排时不要把/y /z当成永不阻塞的保证要给每个子进程设超时并把超时未完成当成一种独立的失败态第 16 篇的账本会处理这个优先让错误在入口被拦截——这就是第 05~08 篇要做的文本生成后先回读校验。1.6 CAESAR II 侧的分工Start Run与Batch Run按公开技术资料的一致描述以官方 CAESAR II 用户手册为准入口行为Start Run保存数据文件调用Piping Error Checker输入错误检查停下等人处理Batch Run保存数据文件、调用错误检查、然后直接继续分析全程无用户交互仅致命错误才中断结果显示在Static Output Processor这个分工的意义Start Run是白天查错Batch Run是夜里跑量两者都先保存——说明保存语义在这套产品里是运行的前置不是一个可选动作。另外 CAESAR II 15.1 引入了新的New Analysis Reviewer官方描述以现代方式查看图形与表格结果、含热力图与位移、生成报告带实时预览与性能改进它是既有Output Reviewer的补充做报告交付时值得优先评估。二、完整代码与逐行剖析代码 03-1run_first.bat——最小批处理算例两套软件各一条echo off REM run_first.bat —— 第一个批处理算例 REM 纪律本文件里的每一个开关都必须小写开关之间至少一个空格 REM 占位符 AUTOPIPE_EXE 请替换为你本机 AutoPIPE.exe 的完整路径 setlocal set APAUTOPIPE_EXE set PROJD:\StressDev\SYS-101 REM 把当前目录切到模型目录因为 DAT/NTL/CMB/CIIMAP/*.c2u 都是在当前目录找 cd /d %PROJ%\model REM ---- 第一步先只转换、不分析/p确认文件能被正确读入 ---- REM /p 把 AutoPIPE Batch 或 AutoPLANT PXF 文件转换为 AutoPIPE 数据库 %AP% SYS101.ntl /p if errorlevel 1 goto :fail REM ---- 第二步静态分析 生成输出报告/s /o---- %AP% SYS101.dat /s /o if errorlevel 1 goto :fail REM ---- 第三步再来一遍附加结果数据库/v供后续取数使用 ---- %AP% SYS101.dat /s /v /o if errorlevel 1 goto :fail echo [OK] 三个步骤全部完成 endlocal exit /b 0 :fail echo [FAIL] 上一步返回非零已中止 endlocal exit /b 1逐行剖析先/p再/s /o是刻意的两步。/p只做格式转换把文件能不能被正确读入与分析能不能收敛这两个失败原因分开。合并成一步的话报错信息会指向错误的方向——这是调试批处理时的第一条实用技巧。cd /d显式切换工作目录。因为 NTL/DAT/CMB/CIIMAP/*.c2u都是在当前目录里找的第 02 篇 1.4 节。/d必须带否则跨盘符切换会失败。if errorlevel 1 goto :fail采用非零即失败的保守判据。注意errorlevel的语义是≥ 该值所以if errorlevel 1覆盖所有非零码。这是 DOS 批处理里最容易写错的比较方式之一。endlocal exit /b用连写endlocal会清掉局部变量因此exit /b必须与它同行——分行写会让退出码丢失。这是批处理的第二个经典坑。不写/y也不写/z。理由见 1.5 节第一次跑我们要的就是看到界面与提示。等这个算例稳定复现之后再考虑在受控环境里加/y /z。代码 03-2run_first.ps1——带产出体检的批处理包装器裸批处理只回答命令有没有返回零。真正的包装器还要回答产出在哪、多大、什么时候生成的、齐不齐。# -*- coding: utf-8 -*-# run_first.ps1 —— 批处理包装器执行 产出物三态体检 退出码分级 设计动机 * 铁律 5先跑通一次但跑通必须由产出物证明不能只由退出码证明 * 铁律 6产出物必须自证存在性 / 规模 / 时效 退出码全系列统一 0 成功1 缺件或空件硬失败3 陈旧需人判断4 执行成功但产出不完整 用法 .\run_first.ps1 -ProjectDir D:\StressDev\SYS-101 -ApExe C:\Program Files\Bentley\AutoPIPE 2025\AutoPIPE.exe .\run_first.ps1 -ProjectDir D:\StressDev\SYS-101 -ApExe ... -DryRun #param([Parameter(Mandatory$true)][string]$ProjectDir,[Parameter(Mandatory$true)][string]$ApExe,[string]$ModelBaseSYS101,# 模型基名不含扩展名[int]$MaxAgeHours 24,[switch]$DryRun,[string]$OutDir)$ErrorActionPreferenceStopif(-not$OutDir){$OutDirJoin-Path$ProjectDirreports}if(-not(Test-Path-LiteralPath$OutDir)){New-Item-ItemType Directory-Path$OutDir|Out-Null}functionInvoke-Step{param([string]$Label,[string[]]$ArgList)$cmd$ApExe ($ArgList-join )Write-Hostn$LabelWrite-Host$cmdif($DryRun){Write-Host (DryRun未真正执行);return0}# 用 Start-Process 拿到真实退出码-Wait 保证串行$pStart-Process-FilePath$ApExe-ArgumentList$ArgList-WorkingDirectory(Join-Path$ProjectDirmodel)-NoNewWindow-Wait-PassThruWrite-Host( 退出码 {0}-f$p.ExitCode)return$p.ExitCode}# ---------- 1) 三步执行 ----------$stepResults ()$stepResults[pscustomobject]{stepconvert (/p);code Invoke-Step转换 NTL - DAT($ModelBase.ntl,/p)}$stepResults[pscustomobject]{stepstatic (/s /o);code Invoke-Step静态分析 报告($ModelBase.dat,/s,/o)}$stepResults[pscustomobject]{stepstaticdb (/s /v /o);code Invoke-Step静态分析 结果MDB 报告($ModelBase.dat,/s,/v,/o)}$hardFail ($stepResults|Where-Object{$_.code-ne0})# ---------- 2) 产出物三态体检 ----------# 说明以下期望产出物的名字形态来自官方文档*.OUT 报告、*.MDB # 具体文件名与位置以你的实际产出为准因此这里用通配时效判定$now Get-Date function Inspect-Artifact { param([string]$Kind, [string]$Dir, [string]$Pattern)$files () if (Test-Path -LiteralPath$Dir) {$files (Get-ChildItem -LiteralPath$Dir-Filter$Pattern-File -Recurse -ErrorAction SilentlyContinue) } if ($files.Count -eq 0) { return [pscustomobject]{ kind$Kind; found$false; file; bytes0; age_h; verdictMISSING } }$f$files| Sort-Object LastWriteTime -Descending | Select-Object -First 1$age [math]::Round(($now-$f.LastWriteTime).TotalHours, 2)$v OK if ($f.Length -lt 16) {$v TOO_SMALL } elseif ($age-gt$MaxAgeHours) {$v STALE } return [pscustomobject]{ kind$Kind; found$true; file$f.FullName; bytes$f.Length; age_h$age; verdict$v} }$modelDir Join-Path$ProjectDirmodel$artifacts ( (Inspect-Artifact -Kind OUT_REPORT -Dir$modelDir-Pattern $ModelBase.OUT), (Inspect-Artifact -Kind RESULT_MDB -Dir$modelDir-Pattern *.MDB), (Inspect-Artifact -Kind DAT_MODEL -Dir$modelDir-Pattern $ModelBase.dat) ) # ---------- 3) 落盘 退出码 ----------$stamp Get-Date -Format yyyyMMdd-HHmmss$stepResults| Export-Csv -LiteralPath (Join-Path$OutDirrun_steps_$stamp.csv) -NoTypeInformation -Encoding UTF8$artifacts| Export-Csv -LiteralPath (Join-Path$OutDirrun_artifacts_$stamp.csv)-NoTypeInformation-Encoding UTF8$artifacts|Format-Tablekind,verdict,bytes,age_h-AutoSize$missing ($artifacts|Where-Object{$_.verdict-in(MISSING,TOO_SMALL)}).Count$stale ($artifacts|Where-Object{$_.verdict-eqSTALE}).Countif($hardFail.Count-gt0){Write-Host★ 有步骤返回非零硬失败;exit1}if($missing-gt0){Write-Host★ 有产出物缺失或过小;exit1}if($stale-gt0){Write-Host★ 有产出物陈旧需人判断;exit3}if($artifacts|Where-Object{$_.verdict-eqMISSING}){exit4}Write-Host全部产出物齐全且新鲜;exit0逐行剖析Invoke-Step用Start-Process ... -PassThru拿真实退出码。直接写 $ApExe ...也能执行但拿到$LASTEXITCODE的时机与作用域容易出错Start-Process配-Wait -PassThru是更稳的写法。-WorkingDirectory显式指定为model。这是对 1.2 节当前目录即隐性上下文的机械落实——不要依赖用户从哪启动脚本。-NoNewWindow而不是-WindowStyle Hidden。第一次跑需要看到输出与提示1.1 节等稳定了再考虑隐藏。Inspect-Artifact的三态判定把存在细分成MISSING/TOO_SMALL/STALE/OK。TOO_SMALL阈值取 16 字节用来抓文件生成了但其实是空的/只有头部这种假成功——这是第 01 篇存在性 ≠ 可用性的落地。退出码分四级1硬失败步骤非零或缺件、3陈旧需人判断、4执行与产出都在但仍有未验证项、0全好。0/1/3/4这套分级会在第 16~20 篇被完整复用所以在这里先把语义钉死。最后一行判断写成$artifacts | Where-Object {...}而非计数是刻意留出的扩展位第 18 篇会在这里接超限项计数把结果不好也变成一个能影响退出码的事实。三、常见报错与排查报错 3-1命令写了/m /s /o但模态分析没有执行。现象结果里没有模态。根因命令行开关被忽略——官方明确若基于 Batch Input 文件且文件中的SOLV卡缺少对应选项如MODE选项则相应开关被忽略。开关的真正权力在 NTL 文件的命令卡里。解法打开*.ntl确认SOLV卡是否含MODE选项第 07、10 篇详述SOLV卡把命令行开关与文件内命令卡当作两个必须一致的东西来管理。报错 3-2autopipe命令什么都不做直接退出。现象秒退无任何产出。根因省略了filename——官方明确iffilenameis omitted, all switches are ignored。另一种可能是当前目录不对找不到该文件。解法核对cd /d是否生效用绝对路径或先cd到model目录随后在包装器里把工作目录显式设为model代码 03-2 已做。报错 3-3夜里批处理挂住不动早上发现停在某个提示上。现象进程长时间不返回。根因官方明确遇到错误会显示错误消息并暂停直到用户确认——批处理并不会自己跳过错误。解法不要把/y /z当成永不阻塞的保证给每个子进程设超时把超时未完成当成独立失败态最根本的办法是在入口拦截错误生成文本后先回读校验见第 05~07 篇。报错 3-4批处理里同时写了/e1 /e2 /e3 /e4只得到一份轴测图。现象期望四份实得一份。根因官方明确轴测开关一次只能用其中一个多个时以最后一个为准。解法要多种格式就分成多条命令分别执行在生成配置里对一个算例最多一个轴测开关做前置校验。报错 3-5步骤都返回 0但结果与 GUI 里手工算的不一致。现象数值对不上。根因按概率排序①单位解释不同AutoPIPE 模型单位与 CII 单位文件不一致时尤其明显第 06 篇详述② 命令行开关与文件内命令卡冲突导致实际执行的配置与预期不同③ 上一次会话设定的荷载组合与批量报告选项不同——官方明确报告文件*.OUT的内容由上一次会话中设定的荷载组合与批量报告选项决定若未设定则用默认值。解法用第 04 篇的对象模型把实际生效的配置打印出来比对报告选项必须在一次受控会话里显式设定并固化到文件。四、动手练习练习 1最小批处理用手头任一 AutoPIPE 示例模型官方安装目录C:\ProgramData\Bentley\AutoPIPE xxxx\Examples下有示例复制到工程model\目录改名为不带空格的基名运行代码 03-1 的三步。判定标准三步的退出码均为 0model\下出现*.OUT报告文件且字节数 1000SYS101.dat存在。随后把/p那一步的源文件名故意改成一个不存在的名字第三步之前必须出现非零返回。练习 2产出体检运行.\run_first.ps1 -ProjectDir 你的工程目录 -ApExe AutoPIPE.exe 路径。判定标准生成两份 CSVrun_steps_*.csv与run_artifacts_*.csvrun_artifacts_*.csv含OUT_REPORT、RESULT_MDB、DAT_MODEL三行且verdict列有值退出码为 0。再把-MaxAgeHours设为 0 重跑退出码必须变为 3全部判定为陈旧。练习 3开关顺序验证用-DryRun模式观察包装器打印的命令行。判定标准能说出为什么写了/o /s也不会先出报告能正确复述官方关于执行顺序的那句规则能指出/e1~/e4的去重规则多个时以最后一个为准。思考题无标准答案为什么 AutoPIPE 要设计命令行开关与其在菜单中的热键字母对应、并按固定顺序执行这一整套机制而不是提供一个纯粹的脚本 API验证要点① 从历史看DOS 批处理时代的产品设计留下了什么路径依赖② 从安全看固定执行顺序避免了哪一类致命的误用提示考虑/o与/s的依赖③ 从兼容看这种设计对已有大量存量.BAT脚本的客户意味着什么。五、小结与下一篇预告AutoPIPE 的无人值守执行由三件事组成命令形态autopipe {filename}可带.ntl/.pxf/.cii、参数开关/a /c /d /e1~e4 /f /g /h /i /k /l1~l4 /m /n /o /p /r /s /t /u /v /y /z、执行规则必须小写、空格分隔、任意顺序书写但按固定顺序执行。三条细节决定成败省略filename则所有开关被忽略命令行写了开关但 NTL 卡的SOLV选项缺失时该开关会被忽略——开关的真正权力在文件里/y /z不等于永不阻塞遇到错误仍会暂停等人确认。CAESAR II 侧的分工是Start Run保存 输入错误检查停下等人处理与Batch Run保存 检查 直接分析无用户交互仅致命错误中断结果显示在 Static Output Processor。最后本系列把跑通的定义钉死为不仅退出码为 0产出物还必须通过存在性、规模与时效三态体检。下一篇《心智模型从主/辅电子表格到命令卡两套软件的对象模型》会讲清两套软件模型是什么这件事CAESAR II 的主电子表格 辅助电子表格数据组织、AutoPIPE 的管点序列 命令卡对应关系以及官方明确的那句两种方法殊途同归对二次开发的真实含义——文件即模型。本篇认知问题回显FAQQ1为什么批处理必须先在 GUI 跑通一次A因为无人值守会失去三条反馈没有结果对比基准、误差会被批量放大、以及成功但错误的产出会进入交付流程——后者比直接失败更危险。正确顺序是在 GUI 手工建最小模型并跑出可复现结果再另存为文本再用命令行重跑同一模型比对结果一致最后才把参数换成变量开始批量。Q2AutoPIPE 的批处理命令形态与参数开关有哪些A命令形态为autopipe {filename} /h /s /m /r /a /f /i /g /o /t /v /n{filename}可带.ntlBatch、.pxfAutoPLANT、.ciiCaesar 中立文件扩展名省略 filename 则所有开关被忽略。开关包括/a谐波、/c热瞬态、/d输入清单 MDB、/e1~e4应力轴测 DGN/DWG/DXF/2D DGN、/f力谱、/g输入清单、/h吊架设计、/i地震锚点位移、/k导出 NTL、/l1~l4EN1591 法兰报告 TXT/CSV/PDF/DOCX、/m模态、/n法兰分析、/o输出报告、/p转为 DAT、/r响应谱、/s静态、/t时程、/uEN1591 法兰分析、/v结果 MDB、/y自动应答消息、/z抑制 GUI。Q3参数开关的书写顺序为什么不影响执行顺序A官方规定开关必须小写、至少以一个空格分隔、可以任意顺序列出但因参数开关与其在 Analyze 与 Result 菜单中的热键字母对应AutoPIPE 一律按文档所示固定顺序执行与书写顺序无关。这是安全设计开关之间存在依赖如生成输出报告依赖先完成分析若按书写顺序执行写成/o /s就会在未分析时去出报告。Q4/y和/z能实现真正的无人值守吗A不能完全保证。/y是自动应答所有消息提示、/z是抑制 AutoPIPE GUI但官方同时说明执行期间大多数交互界面仍会显示且遇到错误会显示错误消息并暂停、直到收到用户确认。因此无用户交互指不需要用户点菜单填对话框不等于出错能自己走下去。工程上应给每个子进程设超时、把超时当作独立失败态并优先在入口拦截错误。Q5CAESAR II 的 Start Run 与 Batch Run 分工是什么A按公开技术资料的一致描述Start Run 保存数据文件并调用 Piping Error Checker 做输入错误检查后停下等人处理Batch Run 则保存数据文件、调用错误检查、然后直接继续分析全程无用户交互仅在遇到致命错误时才中断结果显示在 Static Output Processor。两者都先保存数据文件说明保存是运行的前置动作细节以官方 CAESAR II 用户手册为准。