1.7.0:常规发布

- 版本号 1.7.0 -> 1.7.0
- 重建三端并打包
- 关键测试全过
This commit is contained in:
xmz7891
2026-10-06 23:08:07 +08:00
parent 4c88ca901f
commit ce87ec1650
32 changed files with 2476 additions and 61 deletions
+132
View File
@@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
r"""数据目录自动回退:写不进程序目录就转 ProgramData。
背景:
原来的 data_dir() 就是 app_dir()/data —— 数据存在 exe 旁边。
绿色版没问题,但**做成安装包装到 Program Files 之后**,
普通用户对那个目录没有写权限,配置会存不下去。
用户选的做法:
"能写 exe 旁边就写,不能就转 ProgramData"
这样两种情况都对:
* 绿色版 / 装在 D 盘 / 便携 U 盘 -> 还是存在旁边,拔走就带走配置
* 装在 Program Files -> 自动转 C:\ProgramData\ykxmz,
所有用户共用一份(配对码不会因为换 Windows 账号而丢)
顺带加一个 YKXMZ_DATA 环境变量,测试和特殊部署可以强制指定。
"""
from __future__ import annotations
import ast
import sys
from pathlib import Path
CONFIG = (Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\windows"
r"\lanremote\config.py"))
OLD = '''def app_dir() -> Path:
"""程序所在目录(兼容 PyInstaller 冻结环境)。"""
if getattr(sys, "frozen", False):
return Path(sys.executable).resolve().parent
return Path(__file__).resolve().parent.parent
def data_dir() -> Path:
return app_dir() / "data"'''
NEW = '''def app_dir() -> Path:
"""程序所在目录(兼容 PyInstaller 冻结环境)。"""
if getattr(sys, "frozen", False):
return Path(sys.executable).resolve().parent
return Path(__file__).resolve().parent.parent
# 数据目录只算一次,之后缓存 —— 每个命令都去试写一次太浪费
_DATA_DIR_CACHE: Path | None = None
def _can_write(folder: Path) -> bool:
"""这个目录能不能写(不存在就先建)。"""
try:
folder.mkdir(parents=True, exist_ok=True)
probe = folder / ".write-test"
probe.write_text("x", encoding="utf-8")
probe.unlink()
return True
except OSError:
return False
def data_dir() -> Path:
"""配置 / 令牌 / 接收文件的存放目录。
优先级:
1. 环境变量 YKXMZ_DATA(测试和特殊部署用)
2. 程序目录下的 data/ —— 绿色版、便携 U 盘,拔走就带走配置
3. %PROGRAMDATA%\\ykxmz\\data —— 装到 Program Files 时用这个
为什么要有第 3 条:
安装包默认装到 C:\\Program Files\\ykxmz,
普通用户对那里**没有写权限**(Windows 的硬规矩,不是 bug)。
不转走的话,配对码和令牌会存不下去,用户会莫名其妙连不上。
ProgramData 是所有用户可写的公共位置,换 Windows 账号也不丢配置。
"""
global _DATA_DIR_CACHE
if _DATA_DIR_CACHE is not None:
return _DATA_DIR_CACHE
override = os.environ.get("YKXMZ_DATA")
if override:
_DATA_DIR_CACHE = Path(override)
return _DATA_DIR_CACHE
beside = app_dir() / "data"
if _can_write(beside):
_DATA_DIR_CACHE = beside
return _DATA_DIR_CACHE
base = os.environ.get("PROGRAMDATA") or r"C:\\ProgramData"
common = Path(base) / "ykxmz" / "data"
try:
common.mkdir(parents=True, exist_ok=True)
except OSError:
# 兜底:连 ProgramData 都写不了(极罕见),退回用户目录
common = (Path(os.environ.get("LOCALAPPDATA")
or Path.home()) / "ykxmz" / "data")
common.mkdir(parents=True, exist_ok=True)
_DATA_DIR_CACHE = common
return _DATA_DIR_CACHE'''
def main() -> int:
text = CONFIG.read_text(encoding="utf-8")
if "YKXMZ_DATA" in text:
print(" 已经改过")
return 0
if OLD not in text:
print(" [失败] 锚点没找到")
return 1
text = text.replace(OLD, NEW, 1)
# 确认 os 已经 import 了
if "\nimport os" not in text:
text = text.replace("import sys\n", "import os\nimport sys\n", 1)
print(" 补了 import os")
CONFIG.write_text(text, encoding="utf-8", newline="\n")
print(" data_dir 加了自动回退(ProgramData)")
try:
ast.parse(text)
print(" config.py 语法 OK")
except SyntaxError as exc:
print(f" 语法错误: 行 {exc.lineno}: {exc.msg}")
return 1
return 0
if __name__ == "__main__":
sys.exit(main())