ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Aspen HYSYS 二次开发系列教程(4):Python(pywin32) 最小脚本——位数一致与 Dispatch 失败的第一性排查

Aspen HYSYS 二次开发系列教程(4):Python(pywin32) 最小脚本——位数一致与 Dispatch 失败的第一性排查

Aspen HYSYS 二次开发系列教程(4):Python(pywin32) 最小脚本——位数一致与 Dispatch 失败的第一性排查

版本声明块

  • 软件:aspenONE V15(基线,同第 1 篇);文档现实:Customization Guide V7.3(2011-03)为公开手册基线
  • 语言/环境:Python 3.x + pywin32(Windows);pywin32 位数必须与 64 位 HYSYS 一致(铁律 3)
  • 本文目标:跑通进程外最小脚本,建立"位数为第一排查项"的诊断顺序

一句话结论:pywin32 通过win32com.client.Dispatch("HYSYS.Application")调用同一个 COM 服务器;Dispatch 失败的第一性根因是位数不匹配或 ProgID 未注册——64 位 HYSYS 必须配 64 位 Python(铁律 3),且平台规格中的 Python 3.9–3.12 指宿主语言支持范围而非官方 SDK。

〇、本篇要解决的认知问题

  1. 为什么"位数一致"是 COM 自动化最硬的约束?32 位 Python 连 64 位服务器会发生什么?
  2. ProgID 未注册时 Dispatch 给什么错误?怎么确认注册状态?
  3. 无 GUI 批处理形态(Visible=False)与界面内操作有什么行为差异?
  4. 脚本里"连接已运行实例"与"新建实例"在许可计数上有什么区别?
  5. 最小脚本的可复现性要素是什么——缺哪一样第三方跑不了?

一、机制解析

1.1 位数一致为什么是硬约束(价值锚点:这是最高频的第一道报错)

COM 进程外调用走跨进程 marshalling;64 位服务器(HYSYS 流程模拟器为 64 位)与 32 位 Python 进程之间不能直接共享进程内对象模型——表现就是 Dispatch 报 “ActiveX component can’t create object”。这不是版本问题,是架构层约束(铁律 3)。

排查顺序(固定为四步):

  1. python -c "import struct; print(struct.calcsize('P')*8)"→ 确认 Python 位数;
  2. regedit 查 ProgIDHYSYS.Application是否有有效条目(安装+许可完整才会注册);
  3. 确认 HYSYS 实际运行版本(报告写实际运行版本——铁律 1);
  4. 最小脚本复跑。

1.2 无 GUI 形态的行为差异

Visible=True(界面内)Visible=False(批处理)
GUI 对象访问✓(VBA/进程内才完整——第 3 篇边界表)进程外仅文档/数据对象
许可计数按实例算(第 15 篇)同——服务形态要显式管理实例数
报表联动可触发界面报表需走导出路径(第 13 篇)

1.3 连接 vs 新建的许可语义

GetObject 连接已运行实例不新增实例;CreateObject/Dispatch 可能新建——多实例并存时许可计数与"对象挂错文档"风险同时上升(第 2 篇)。经验法则:服务形态固定一种方式并在报告注明实例数与许可形态(第 15 篇部署清单)。

二、完整代码与逐行剖析

2.1 最小可运行脚本(复制即跑)

importwin32com.client,structassertstruct.calcsize('P')*8==64,"Python must be 64-bit to match 64-bit HYSYS (铁律 3)"app=win32com.client.Dispatch("HYSYS.Application")# ProgID 解析到当前安装版本(铁律 1)app.Visible=False# 无 GUI 批处理形态(1.2)sim=app.ActiveDocument# 单窗口场景;服务用 Documents 遍历(第 2 篇)feed=sim.Flowsheet.MaterialStreamFlowsheetStreams.Item("Feed")# 名称以本机为准(铁律 7)print("T:",feed.Temperature.Value,"P:",feed.Pressure.Value)

逐行要点:assert位数检查是脚本的"自诊断第一行"——把本篇机制落成代码;属性名 Temperature/Pressure 属已确证形态,其余未证实处一律标注(铁律 7)。

2.2 可复现性三件套(判定线)

第三方跑通的最小条件:① 脚本含位数断言与 ProgID 注释;② 对象名约定表(“Feed” 等名称契约——第 19 篇);③ 版本快照(实际运行版本)。判定标准:按三件套在另一台机器复跑,输出一致(相对误差 < 1e-6)。

三、常见报错与排查

  1. ActiveX component can't create object—— 根因:位数不匹配或 ProgID 未注册(1.1)。解法:按四步排查顺序;换 64 位 Python 或修复安装/许可。
  2. Dispatch 成功但 ActiveDocument 为 None—— 现象:脚本第二段崩溃。根因:无打开的 case(文档层断链——第 2 篇对象链)。解法:先打开 case 或在脚本内显式新建;服务形态用 Documents 遍历绑定。
  3. Item(“Feed”) 失败—— 根因:名称契约破坏(大小写/后缀)或流股在另一 case。解法:列容器成员再索引(第 2 篇)。
  4. 许可超限—— 现象:多实例脚本报 license error。根因:许可按实例计数(1.3、第 15 篇)。解法:串行化;固定连接方式并记录实例数。

四、动手练习

  1. 四步排查复现:在另一台机器上先制造一次位数不匹配(32 位 Python),按 1.1 顺序修复。判定标准:报错文本与根因对应正确;修复后最小脚本输出一致(< 1e-6)。
  2. 无 GUI 形态验证:Visible=False 下完成读值。判定标准:不弹任何窗口且结果与 GUI 一致;写出"哪些功能在进程外不可用"的三行清单(第 3 篇边界表复用)。
  3. 思考题(无标准答案):为什么服务形态必须固定连接方式?验证要点清单:① 写出 GetObject/CreateObject 对许可计数的不同影响;② 举一个多实例并存导致对象挂错文档的场景;③ 给出报告应记录的三项信息(实例数、许可形态、运行版本)。

五、小结与下一篇预告

本篇把位数一致确立为 COM 自动化的第一性约束并给出四步排查顺序。下一篇进入属性读写的完整模式——.Temperature.Value这类"值-单位"两级结构,以及未证实属性名的本机自查纪律(铁律 7),为第 7 篇单位陷阱铺路。


本篇认知问题回显(FAQ)

Q1:pywin32 调用 Aspen HYSYS 时为什么位数必须一致?

A:进程外 COM 调用跨进程 marshalling——64 位流程模拟器与 32 位 Python 进程不能直接共享进程内对象模型,Dispatch 报 “ActiveX component can’t create object”;这是架构层约束(铁律 3),不是版本问题。

Q2:平台规格文档里的 Python 3.9–3.12 指什么?

A:指 pywin32 可调用 COM 服务器的宿主语言版本支持范围——AspenTech 没有公开发布官方 Python SDK;Python 路线是社区用 pywin32 通过 ProgID HYSYS.Application 调用同一个 COM 服务器。

Q3:Dispatch 失败的第一性排查顺序是什么?

A:① 确认 Python 位数(struct.calcsize(‘P’)*8);② regedit 查 ProgID HYSYS.Application 注册条目(安装+许可完整才会注册);③ 确认实际运行版本;④ 最小脚本复跑。

Q4:Visible=False 的无 GUI 形态与界面内操作有什么差异?

A:进程外脚本只能走文档/数据对象、不能访问 GUI 对话框;许可按实例计数不变;报表需走导出路径——服务形态应固定连接方式并记录实例数与许可形态。

Q5:一个可复现的 HYSYS 自动化脚本最小需要哪三样?

A:位数断言与 ProgID 注释、对象名契约表(如 “Feed” 的名称约定)、实际运行版本快照——三者齐则第三方可在另一台机器复跑并得到一致结果。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进