# -*- 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())