fix: 水池截面中转文件 JMSJ.sat 按进程隔离,补临时文件命名文档
JMDBDlg、JMSJDlg、HZQTDlg 共 7 处共用固定的 JMSJ.sat,两个 CAD 实例 同时运行时会互相覆盖,acisIn 可能读到另一个实例写的截面。 新增 Pool3dCmd/PoolSectionTemp.h 的 GetPoolSectionSatPath(),文件名改为 JMSJ_<pid>.sat。同一进程内所有调用点路径一致,acisOut 写、ShowLastSection 读的隐式链路不受影响;进程之间用 PID 隔离。顺带去掉无意义的 MakeLower。 同时新增 temp-file-naming.md,记录临时文件命名规则、全库现状,以及 DGJM.sat 已废弃、不再改造的结论。
This commit is contained in:
1 parent
e3fff2ad66
commit
8caea9e6bd
5 files changed
+86
-17
No files matched your search
@@ -4,6 +4,7 @@
|
||||
#include "JMSJDlg.h"
|
||||
#include "GLTKDlg.h"
|
||||
#include "KTSetting.h"
|
||||
#include "PoolSectionTemp.h"
|
||||
|
||||
DLLIMPEXP CString IDCreate();
|
||||
|
||||
@@ -270,9 +271,7 @@ void CHZQTDlg::OnBnClickedCheck1()
|
||||
CString sScr;
|
||||
if (dlg.GetCrossSectionScr(sScr))
|
||||
{
|
||||
CString sFullPath = FilePath::GetSysDir();
|
||||
sFullPath.MakeLower();
|
||||
sFullPath += _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::GetSysDir());
|
||||
|
||||
CStdioFile file;
|
||||
if (file.Open(sFullPath,CFile::modeCreate |CFile::modeWrite ))
|
||||
@@ -394,9 +393,7 @@ void CHZQTDlg::SetFromWall(AcDbObjectId& id)
|
||||
m_bUserDefSec = TRUE;
|
||||
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECTIONSCR,m_sRegScr);
|
||||
|
||||
CString sFullPath = FilePath::GetSysDir();
|
||||
sFullPath.MakeLower();
|
||||
sFullPath += _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::GetSysDir());
|
||||
|
||||
CStdioFile file;
|
||||
if (file.Open(sFullPath,CFile::modeCreate |CFile::modeWrite ))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "JMDBDlg.h"
|
||||
#include "GLTKDlg.h"
|
||||
#include "CoreTools.h"
|
||||
#include "PoolSectionTemp.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC(CJMDBDlg, CDialog)
|
||||
|
||||
@@ -87,9 +88,7 @@ void CJMDBDlg::OnBnClickedButton1()
|
||||
CString sScr;
|
||||
if (dlg.GetCrossSectionScr(sScr))
|
||||
{
|
||||
CString sFullPath = FilePath::GetSysDir();
|
||||
sFullPath.MakeLower();
|
||||
sFullPath += _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::GetSysDir());
|
||||
|
||||
CStdioFile file;
|
||||
if (file.Open(sFullPath,CFile::modeCreate |CFile::modeWrite ))
|
||||
@@ -173,7 +172,7 @@ void CJMDBDlg::OnBnClickedButton2()
|
||||
|
||||
if (m_pSectionReg != NULL && bSuccess)
|
||||
{
|
||||
CString sFullPath = FilePath::getSystemTemporaryFolder() + _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::getSystemTemporaryFolder());
|
||||
|
||||
CString sRegionScrp = _T("");
|
||||
CString sLine;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "JMSJDlg.h"
|
||||
#include "CoreTools.h"
|
||||
#include "PoolSectionTemp.h"
|
||||
#include "JUXCDlg.h"
|
||||
#include "GLTKDlg.h"
|
||||
#include "BYCDlg.h"
|
||||
@@ -78,9 +79,7 @@ BOOL CJMSJDlg::OnInitDialog()
|
||||
void CJMSJDlg::ShowLastSection()
|
||||
{
|
||||
//1.截面
|
||||
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
||||
sFullPath.MakeLower();
|
||||
sFullPath += _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::getSystemTemporaryFolder());
|
||||
|
||||
AcDbVoidPtrArray arBodyPtrs;
|
||||
if ( Acad::eOk == AcDbBody::acisIn(sFullPath,arBodyPtrs) )
|
||||
@@ -139,7 +138,7 @@ void CJMSJDlg::OnBnClickedBtaddtodb()
|
||||
UpdateData(TRUE);
|
||||
|
||||
if (!m_curSection.pReg) return;
|
||||
CString sFullPath = FilePath::getSystemTemporaryFolder() + _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::getSystemTemporaryFolder());
|
||||
|
||||
CString sRegionScrp = _T("");
|
||||
CString sLine;
|
||||
@@ -425,9 +424,7 @@ void CJMSJDlg::OnBnClickedBtselfromdb()
|
||||
CString sScr,sScrT;
|
||||
if (dlg.GetCrossSectionScr(sScr))
|
||||
{
|
||||
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
||||
sFullPath.MakeLower();
|
||||
sFullPath += _T("\\JMSJ.sat");
|
||||
CString sFullPath = GetPoolSectionSatPath(FilePath::getSystemTemporaryFolder());
|
||||
|
||||
CStdioFile file;
|
||||
if (file.Open(sFullPath,CFile::modeCreate |CFile::modeWrite ))
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// 水池截面 SAT 中转文件路径。
|
||||
// 同一个 CAD 进程内所有调用点返回同一路径;不同进程用 PID 区分,
|
||||
// 避免两个实例同时写同一个 JMSJ.sat 互相覆盖。
|
||||
inline CString GetPoolSectionSatPath(LPCTSTR lpszDir)
|
||||
{
|
||||
CString sPath;
|
||||
sPath.Format(_T("%s\\JMSJ_%lu.sat"), lpszDir, (unsigned long)::GetCurrentProcessId());
|
||||
return sPath;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
# 临时文件命名与多实例安全
|
||||
|
||||
> 记录全库临时文件(ACIS SAT、DWG 中转等)的命名规则、现状与遗留项。
|
||||
> 最后更新:2026-10-22
|
||||
|
||||
## 规则
|
||||
|
||||
1. 文件名必须带 `GetCurrentProcessId()`。同一进程内需要多次独立使用、彼此不能共享的,再加原子递增序号。
|
||||
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 后缀,目录未动。
|
||||
|
||||
统一走 `Pool3dCmd/PoolSectionTemp.h`:
|
||||
|
||||
```cpp
|
||||
inline CString GetPoolSectionSatPath(LPCTSTR lpszDir)
|
||||
{
|
||||
CString sPath;
|
||||
sPath.Format(_T("%s\\JMSJ_%lu.sat"), lpszDir, (unsigned long)::GetCurrentProcessId());
|
||||
return sPath;
|
||||
}
|
||||
```
|
||||
|
||||
同一进程内所有调用点返回同一路径,所以 `acisOut` 写完、`ShowLastSection` 再读这条隐式链路仍然成立;进程之间用 PID 隔离,两个 CAD 实例不会再互相覆盖。
|
||||
|
||||
**已知取舍**:`CJMSJDlg::ShowLastSection` 在 `OnInitDialog` 里读这个文件,本意是恢复上一次用的截面。加 PID 后只能读到本进程内上一次写的,跨进程/跨会话恢复失效。这个能力原本也不可靠——temp 目录会被清理,多实例还会互相覆盖。如果确实需要跨会话记忆,应改存注册表、ini 或文档数据库,而不是靠临时文件。
|
||||
|
||||
## 待处理
|
||||
|
||||
- `PipelineCmd` 的 `temp_$_$_.equ`、`tmp_dwg_$$%d.dwg`:界面导出路径,多实例会冲突,暂未改。
|
||||
Reference in new issue
Block a user