mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 20:40:43 +00:00
125 lines
4.3 KiB
Python
125 lines
4.3 KiB
Python
# -*- 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())
|