Files
ykxmz/_build/fix_datadir_deterministic.py
xmz7891 ce87ec1650 1.7.0:常规发布
- 版本号 1.7.0 -> 1.7.0
- 重建三端并打包
- 关键测试全过
2026-10-06 23:08:07 +08:00

125 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
r"""修:按"能不能写"判断数据目录导致安装版配置分裂。
现象:
安装时(管理员)把 settings.json 写到了
C:\Program Files\ykxmz\data\settings.json
之后普通用户运行时,_can_write() 对那个目录返回 False,
于是转到
C:\ProgramData\ykxmz\data
目录是空的 —— 安装时设的配对码普通用户根本看不到。
根因:
用"当前用户能不能写"来决定数据目录,这个判断**不稳定**:
同一个程序,管理员跑和普通用户跑会得出不同结论,
结果就是配置分裂成两份,谁也看不见谁。
改法:
改成**确定性**判断 —— 看程序装在哪,不看当前是谁在跑:
* 装在 Program Files 下 -> 安装版,数据一律放 ProgramData
* 其它位置(绿色版/D盘/U盘)-> 能写 exe 旁边就写旁边
这样管理员和普通用户看到的是同一份配置。
"""
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"))
# ---------- 1. 加"是不是安装版"的判断 ----------
OLD_MARK = '''def data_dir() -> Path:'''
NEW_MARK = '''def _is_installed_copy() -> bool:
"""程序是不是装在 Program Files 下(也就是"安装版")。
这个判断只跟**程序装在哪**有关,跟"当前是谁在跑"无关 ——
这正是关键:数据目录必须对所有用户是同一个,
否则管理员装的配置普通用户看不见(实测踩过)。
"""
try:
here = str(app_dir()).lower().replace("/", "\\\\")
except OSError:
return False
for name in ("ProgramFiles", "ProgramFiles(x86)", "ProgramW6432"):
base = os.environ.get(name)
if not base:
continue
prefix = str(base).lower().replace("/", "\\\\").rstrip("\\\\")
if here == prefix or here.startswith(prefix + "\\\\"):
return True
return False
def data_dir() -> Path:'''
# ---------- 2. 用它 ----------
OLD_PICK = ''' beside = app_dir() / "data"
if _can_write(beside):
_DATA_DIR_CACHE = beside
return _DATA_DIR_CACHE
# ProgramData:所有用户共用一份配置(换 Windows 账号也不丢)
base = os.environ.get("PROGRAMDATA") or r"C:\\ProgramData"
common = Path(base) / "ykxmz" / "data"
if _can_write(common):
_DATA_DIR_CACHE = common
return _DATA_DIR_CACHE'''
NEW_PICK = ''' # ── 安装版(装在 Program Files)一律用 ProgramData ──
# 不能按"我能不能写 exe 旁边"来判断:
# 安装时是管理员跑的,写得进去;之后普通用户跑就写不进去,
# 于是悄悄换了目录 —— 安装时设的配对码就找不着了(实测踩过)。
# 按"装在哪"判断,管理员和普通用户看到的就是同一份配置。
in_program_files = _is_installed_copy()
beside = app_dir() / "data"
if not in_program_files and _can_write(beside):
_DATA_DIR_CACHE = beside
return _DATA_DIR_CACHE
# ProgramData:所有用户共用一份配置(换 Windows 账号也不丢)
base = os.environ.get("PROGRAMDATA") or r"C:\\ProgramData"
common = Path(base) / "ykxmz" / "data"
if _can_write(common):
_DATA_DIR_CACHE = common
return _DATA_DIR_CACHE'''
def main() -> int:
text = CONFIG.read_text(encoding="utf-8")
ok = True
if "_is_installed_copy" in text:
print(" 已经改过")
return 0
for old, new, label in ((OLD_MARK, NEW_MARK, "加 _is_installed_copy"),
(OLD_PICK, NEW_PICK, "数据目录改成确定性判断")):
if old not in text:
print(f" [失败] {label} —— 锚点没找到")
ok = False
continue
text = text.replace(old, new, 1)
print(f" {label}")
if not ok:
return 1
CONFIG.write_text(text, encoding="utf-8", newline="\n")
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())