Files
envi-code/temp-file-naming.md
T
company-desktop-computer 4e658a8ae9 refactor: 水池截面中转文件改用 CoreTools::getTempFilePath
删除 Pool3dCmd/PoolSectionTemp.h,JMDBDlg、JMSJDlg、HZQTDlg 共 7 处
改为 CoreTools::getTempFilePath(_T("JMSJ_"), _T(".sat"), 目录)。

同时修 getTempFilePath 自身的问题:
- 传了有效父目录时 sParentPath 没有赋值,会拼出 "\JMSJ_xxx.sat"
- 父目录为空时仍对 pszParentPath 调 _taccess,参数可能是 NULL
- return sPath(); 语法错误
- objId 用 %lu 格式化 Adesk::ULongPtr,64 位下会截断,改 %I64u

temp-file-naming.md 同步改为介绍这个通用函数。
2026-10-22 10:06:51 +08:00

4.2 KiB
Raw Blame History

临时文件命名与多实例安全

记录全库临时文件(ACIS SAT、DWG 中转等)的命名规则、现状与遗留项。 最后更新:2026-10-22

规则

  1. 文件名必须带 GetCurrentProcessId(),直接用 CoreTools::getTempFilePath() 生成。同一进程内需要多次独立使用、彼此不能共享的,再加原子递增序号。
  2. 用完即删(::DeleteFile)。写读双方跨函数隐式传递的文件除外,见下文 JMSJ.sat。
  3. 路径统一用 FilePath::getSystemTemporaryFolder(),不要落到安装目录。
  4. 从 DWG 里读回来的文件名不可信,必须只取纯文件名,拒绝 ..\、盘符等路径成分。
  5. 从文件读进缓冲区再当字符串用时:分配 nLen + 1、清零,按 Read 实际返回的长度构造 CString,不要直接 CString = pszTxt。

现状

位置 改前 改后 状态
CoreCommand/CoreTools.cpp MakeTempSatPath — x3d_<pid>_<seq>.sat 已符合,调用方负责删除
CoreLibrary/AcDbX3dSolid.cpp CreateFromSat temp\temp.sat temp_<pid>_<seq>.sat 已修,用完删除
CoreLibrary/AecDbEwPipeBase.cpp RegionAcisoutDwgOutFields Region_<handle>.dat Region_<pid>_<tag>.dat 已修;未入库实体无句柄时用序号 N<n>
Pool3dCmd/JMDBDlg.cpp JMSJDlg.cpp HZQTDlg.cpp JMSJ.sat JMSJ_<pid>.sat 已修,见下文
CoreCommand/KTEarthWormCmd.cpp CO_RGCSCmdFnc Region_<handle>.dat 未改 测试命令,不在产品链路,暂不处理
DGJM.sat 20 处 DGJM.sat 未改 代码已废弃,见下文
PipelineCmd temp_$_$_.equ、tmp_dwg_$$%d.dwg 固定名 未改 界面导出路径,多实例会冲突,低优先级

DGJM.sat:废弃代码,不再处理

分布:AcDbX3dSolid.cpp(2)、AecDbEarthWormFitting.cpp(2)、AcDbX3dGroup.cpp(3)、EarthWormCmd/*(13)。

这是写方 acisOut 和读方 acisIn 之间的隐式约定:A 函数把 region 写到固定文件,B 函数再从同一个文件读回来。加 PID 或序号会让读方找不到文件,必须先把接口改成「写方返回路径、读方接收路径」才能动。

该链路已整体废弃,文件名保持原样,不再改造。只在 PR #31 中修了读取越界:new char[n] 后直接赋给 CString 会把堆里的随机字节当字符串读,现改为 new char[n+1] + 清零 + 按实际长度构造。涉及 AcDbX3dSolid、AecDbEarthWormFitting、DGJMDlg、GJYXJMDlg、JMDBDlg、JMSJDlg 共 6 处。

若将来这段代码被复用,先改接口,再按本文规则命名。

JMSJ.sat:水池截面中转

7 处,分布在 3 个文件:

文件 用途
JMDBDlg.cpp 从标准库选截面(写)→ acisIn;acisOut 导出截面字符串(读)
JMSJDlg.cpp ShowLastSection 读上次截面;入库时 acisOut 导出;从标准库选截面(写)→ acisIn
HZQTDlg.cpp 从标准库选截面(写)→ acisIn,两处

目录原本分两套:JMDBDlg / JMSJDlg 用 FilePath::getSystemTemporaryFolder(),HZQTDlg 用 FilePath::GetSysDir()(安装目录下的 sys)。两套互不相干,本次只加 PID 后缀,目录未动。

统一走 CoreTools::getTempFilePath()(CoreCommand/CoreTools.cpp):

CString sFullPath = CoreTools::getTempFilePath(_T("JMSJ_"), _T(".sat")
	, FilePath::getSystemTemporaryFolder());
// -> <temp>\JMSJ_<pid>.sat

getTempFilePath 是通用工具:主名 + 可选进程号 + 可选实体 id + 后缀;父目录为空或不存在时落到系统临时目录。

同一进程内所有调用点返回同一路径,所以 acisOut 写完、ShowLastSection 再读这条隐式链路仍然成立;进程之间用 PID 隔离,两个 CAD 实例不会再互相覆盖。

已知取舍:CJMSJDlg::ShowLastSection 在 OnInitDialog 里读这个文件,只用于对话框打开时显示上一个设计好的截面,不是功能数据。加 PID 后新进程读不到上个进程留下的截面,已确认可接受。

待处理

  • PipelineCmd 的 temp_$_$_.equ、tmp_dwg_$$%d.dwg:界面导出路径,多实例会冲突,暂未改。