Files
90CNServer/launcher/README.md
T
hanfuit c6587d88ee 启动器:修复打包后自我套娃开窗,补运行日志与排查文档
根因:start_gmweb() 用 sys.executable 拉起 gmweb/serve.py,源码运行时是
python.exe,PyInstaller 单文件打包后却是启动器自身 —— 于是 `exe serve.py`
又开了一个启动器,新启动器再去拉 serve.py,每代顺延一个端口并各开一个
空窗口,直到 19546 端口用尽。开发机因为 18112 早被占用走了 early return,
所以看不出来。

- 新增多调用模式 run_script_instead():exe <xxx.py> [args] 时用 runpy 直接
  执行该脚本,不开窗口/不提权/不占互斥量,打包后拉起 serve.py 才合法
- 新增单实例互斥(Local\DNF90Launcher-5E9C1B7A):重复启动把已有窗口
  ShowWindow+SetForegroundWindow 后退出,不再开第二个窗口
- start_gmweb() 增加就绪校验:spawn 后最多等 6 秒确认 18112 在监听,未监听
  则改用 importlib 在本进程线程里跑 serve.py 的 main(),绝不再拉起新窗口
- self_elevate() 提权重启带上原始参数(原来 ShellExecuteW 传 None,参数全丢);
  DNF90_GMWEB_CHILD=1 的子进程不再触发 UAC
- WebView2 数据目录固定到 %LOCALAPPDATA%\DNF90Launcher\WebView2 且
  private_mode=False,避免 exe 在只读目录/网络盘时窗口空白且无报错;
  启动前查注册表确认运行时是否存在
- 新增 启动器日志.txt(exe 同目录,512KB 转 .old.txt):console=False 下
  print 与未捕获异常全部落盘,顶部记录 pid/argv/SERVER_ROOT
- 文档:新增 docs/启动器窗口风暴排查.md(现象、根因、复现手法、修复点、
  日志判读表),README 常见坑与文档索引、docs/README、launcher/README 同步
2026-11-05 17:22:51 +08:00

42 lines
2.0 KiB
Markdown
Raw 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.
# 整合启动器 + GM 管理工具
单 EXE 的 DNF90 启动器,内置完整 GM 管理工具(角色管理、道具发放、邮件、背包装备、拍卖行、任务、副本、钱包点券、删档等)。
## 技术栈
- **Python 3.15**(32 位)+ **pywebview 6.x**(Edge WebView2 内嵌窗口)
- 纯标准库 HTTP 后端 + 原生 HTML/CSS/JS 前端
- **PyInstaller** 打包单文件 EXE
## 文件说明
| 文件 | 说明 |
|------|------|
| `server.py` | 整合后端(启动器 + GM 工具,纯标准库) |
| `db.py` | SQLite 数据访问层(删角色/删档/疲劳/物品名缓存) |
| `native.py` | Native API 客户端(完整 GM 端点) |
| `index.html` / `style.css` / `app.js` | 双视图前端 |
| `DNF90启动器.spec` | PyInstaller 打包配置 |
| `sponsor.png` / `sponsor_qr.png` | 赞助二维码 |
| `qr/` | 关于页二维码(alipay / wechat / gzh / qq,可被 exe 同目录的同名文件覆盖) |
| `启动器日志.txt` | 运行日志(运行时生成,exe 同目录,超过 512KB 转 `.old.txt`) |
## 运行时约定
- **单实例**:命名互斥量 `Local\DNF90Launcher-5E9C1B7A`,重复启动只会把已有窗口提到前台
- **多调用模式**:`DNF90启动器.exe <xxx.py> [args]` 会用 `runpy` 直接执行该脚本。打包后 `sys.executable` 就是 exe 自己,`start_gmweb()` 正是靠这条路径拉起 `gmweb/serve.py` 的
- **提权**:UAC 自提权重启会带上原始参数;`DNF90_GMWEB_CHILD=1` 的子进程不再提权
- **WebView2 数据目录**:固定在 `%LOCALAPPDATA%\DNF90Launcher\WebView2`,避免 exe 在只读目录/网络盘时窗口空白
- 排障与现场取证见 [`docs/启动器窗口风暴排查.md`](../docs/启动器窗口风暴排查.md)
## 打包
```bash
cd launcher
python -m pip install pywebview pythonnet clr-loader pyinstaller
python -m PyInstaller --clean --noconfirm "DNF90启动器.spec"
# 产物:dist/DNF90启动器.exe
```
> 详见 [`docs/开发文档.md`](../docs/开发文档.md) 完整说明(环境搭建、架构、API 契约、常见问题)。