2026-05-21 11:20:19 +08:00
|
|
|
|
# GPU Guard Windows 离线安装方案设计
|
2026-05-20 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
> 日期:2026-04-25
|
|
|
|
|
|
> 状态:待实施
|
|
|
|
|
|
> 修订:v3 — 补充数据库凭证外置、config 校验、启动顺序、网络驱动器约束、CLI 版本参数、卸载进程停止
|
|
|
|
|
|
|
|
|
|
|
|
## 目标
|
|
|
|
|
|
|
2026-05-21 11:20:19 +08:00
|
|
|
|
将 GPU Guard 智能管理审核平台(Vue 3 前端 + Midway.js 后端)打包为 **单个离线 Windows 安装器 exe**。
|
|
|
|
|
|
目标用户是 Windows 用户,安装后双击即可使用,无需安装 Node.js、数据库等开发环境。
|
2026-05-20 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
## 约束
|
|
|
|
|
|
|
|
|
|
|
|
- 交付形式:单个 `setup.exe`,离线安装,不依赖网络
|
|
|
|
|
|
- 安装后体验:双击桌面快捷方式 → 启动后端 → 自动打开浏览器访问前端首页
|
|
|
|
|
|
- 数据库:MySQL 在云端,本地不安装
|
|
|
|
|
|
- 本地持久化:所有本地文件(上传、缓存、插件、skills、agent 记忆、session 树等)统一写入用户选择的数据目录
|
|
|
|
|
|
- 支持:安装、卸载、重装
|
|
|
|
|
|
- 预留:未来版本更新机制(本期不实现)
|
|
|
|
|
|
- 支持:桌面启动 + 可选开机自启
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 安装后目录结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2026-05-21 11:20:19 +08:00
|
|
|
|
[安装目录,默认 C:\Program Files\GPUGuard]
|
2026-05-20 21:39:12 +08:00
|
|
|
|
├── backend.exe # 主程序(pkg 产物,内含前端静态资源)
|
|
|
|
|
|
├── config.yaml # 运行配置(安装器生成,用户可编辑)
|
|
|
|
|
|
├── unins000.exe # 卸载器(Inno Setup 自动生成)
|
|
|
|
|
|
└── unins000.dat
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2026-05-21 11:20:19 +08:00
|
|
|
|
[数据目录,默认 C:\GPUGuardData,安装时用户选择]
|
2026-05-20 21:39:12 +08:00
|
|
|
|
├── uploads/ # 文件上传(原 {cwd}/dist/upload/)
|
|
|
|
|
|
├── cache/ # 文件缓存(原 {cwd}/dist/cache/)
|
|
|
|
|
|
├── plugins/ # 插件文件(原 {cwd}/dist/plugin/)
|
|
|
|
|
|
├── cool.sqlite # Cool Admin 本地 SQLite(原 {cwd}/dist/cool.sqlite)
|
|
|
|
|
|
├── skills/ # Agent 技能安装目录(原 {cwd}/skills/)
|
|
|
|
|
|
├── .skillhub/ # Skill 元数据和锁文件(原 {cwd}/.skillhub/)
|
|
|
|
|
|
├── memory/
|
|
|
|
|
|
│ └── memory.db # Agent 记忆 SQLite(原 ~/.neta/memory/memory.db)
|
|
|
|
|
|
├── sessions/ # Session 树文件(原 ~/.neta/sessions/)
|
|
|
|
|
|
├── logs/ # 运行日志(按天滚动,保留 30 天)
|
|
|
|
|
|
└── neta.lock # 进程锁文件
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
核心原则:**程序目录只读,数据目录可写,完全分离**。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 路径统一方案(v2 新增)
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 现状:两套独立路径体系
|
|
|
|
|
|
|
|
|
|
|
|
| 路径体系 | 解析方式 | 内容 |
|
|
|
|
|
|
|----------|----------|------|
|
|
|
|
|
|
| `comm/path.ts` | `process.cwd()/dist/...` | uploads、cache、plugin、cool.sqlite |
|
|
|
|
|
|
| `netaclaw.dataDir` | `~/.neta/` | agent memory SQLite、session tree |
|
|
|
|
|
|
| skill 系统 | `process.cwd()/skills/` | 技能文件、.skillhub 元数据 |
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 改造:统一到 config.yaml 的 `data.dir`
|
|
|
|
|
|
|
|
|
|
|
|
新增一个启动早期的路径初始化模块 `comm/data-dir.ts`:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
// 优先级:config.yaml data.dir > 环境变量 NETA_DATA_DIR > 默认 ./data
|
|
|
|
|
|
export function resolveDataDir(): string;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
改造 `comm/path.ts` 中所有路径函数,使其从 `resolveDataDir()` 派生:
|
|
|
|
|
|
|
|
|
|
|
|
| 函数 | 改造前 | 改造后 |
|
|
|
|
|
|
|------|--------|--------|
|
|
|
|
|
|
| `pUploadPath()` | `{cwd}/dist/upload/` | `{dataDir}/uploads/` |
|
|
|
|
|
|
| `pCachePath()` | `{cwd}/dist/cache/` | `{dataDir}/cache/` |
|
|
|
|
|
|
| `pPluginPath()` | `{cwd}/dist/plugin/` | `{dataDir}/plugins/` |
|
|
|
|
|
|
| `pSqlitePath()` | `{cwd}/dist/cool.sqlite` | `{dataDir}/cool.sqlite` |
|
|
|
|
|
|
|
|
|
|
|
|
改造 `netaclaw` 配置:
|
|
|
|
|
|
|
|
|
|
|
|
| 配置项 | 改造前 | 改造后 |
|
|
|
|
|
|
|--------|--------|--------|
|
|
|
|
|
|
| `netaclaw.dataDir` | `~/.neta` | `{dataDir}` |
|
|
|
|
|
|
| `netaclaw.skillsDir` | `./skills` | `{dataDir}/skills` |
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 `process.cwd()` 安全处理
|
|
|
|
|
|
|
|
|
|
|
|
pkg exe 运行时 `process.cwd()` 取决于启动方式(快捷方式的"起始位置"、命令行当前目录等),不可靠。
|
|
|
|
|
|
|
|
|
|
|
|
解决方案:
|
|
|
|
|
|
- Inno Setup 创建快捷方式时,设置"起始位置"为安装目录
|
|
|
|
|
|
- `comm/data-dir.ts` 中不依赖 `process.cwd()`,而是:
|
|
|
|
|
|
1. 读取 exe 同目录下的 `config.yaml`(通过 `process.execPath` 定位 exe 目录)
|
|
|
|
|
|
2. 从 `config.yaml` 的 `data.dir` 获取数据目录绝对路径
|
|
|
|
|
|
3. fallback:如果 `config.yaml` 不存在,使用 `{exeDir}/data/` 作为默认值
|
|
|
|
|
|
|
|
|
|
|
|
### 2.4 开发环境兼容
|
|
|
|
|
|
|
|
|
|
|
|
改造后的路径函数需要同时兼容开发环境(`npm run dev`)和打包环境(`backend.exe`):
|
|
|
|
|
|
- 开发环境:无 `config.yaml`,fallback 到 `{cwd}/dist/`(保持现有行为)
|
|
|
|
|
|
- 打包环境:读 `config.yaml`,使用用户选择的数据目录
|
|
|
|
|
|
|
|
|
|
|
|
检测方式:`process.pkg` 存在时为 pkg 环境。
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 外部配置加载机制(v2 新增)
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 安全约束:数据库凭证必须外置
|
|
|
|
|
|
|
|
|
|
|
|
云端 MySQL 的 host / username / password / database **不得硬编码进 exe**。
|
|
|
|
|
|
`config.prod.ts` 中现有硬编码凭证在实施时必须移除,改为全部从外部 `config.yaml` 或安全环境变量读取。
|
|
|
|
|
|
|
|
|
|
|
|
原因:pkg 产物可被逆向分析,硬编码凭证会泄露。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 config.yaml 完整结构
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
server:
|
|
|
|
|
|
port: 8003
|
|
|
|
|
|
|
|
|
|
|
|
data:
|
2026-05-21 11:20:19 +08:00
|
|
|
|
dir: "C:\\GPUGuardData" # 安装器写入用户选择的数据目录绝对路径
|
2026-05-20 21:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
autoOpenBrowser: true
|
|
|
|
|
|
|
|
|
|
|
|
database:
|
|
|
|
|
|
type: mysql
|
|
|
|
|
|
host: ""
|
|
|
|
|
|
port: 3306
|
|
|
|
|
|
username: ""
|
|
|
|
|
|
password: ""
|
|
|
|
|
|
database: ""
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 config.yaml 校验
|
|
|
|
|
|
|
|
|
|
|
|
程序启动时必须对 `config.yaml` 做 schema 校验:
|
|
|
|
|
|
- 必填项缺失(如 `data.dir`)
|
|
|
|
|
|
- 类型错误(如 `port` 不是数字)
|
|
|
|
|
|
- 路径无效(数据目录不存在或不可写)
|
|
|
|
|
|
- 数据库配置不完整
|
|
|
|
|
|
|
|
|
|
|
|
校验失败时:
|
|
|
|
|
|
1. 不启动 Midway
|
|
|
|
|
|
2. 弹出清晰错误信息(Windows MessageBox 或控制台提示)
|
|
|
|
|
|
3. 写入启动失败日志到 `{dataDir}/logs/bootstrap-error.log`(若 dataDir 可用)
|
|
|
|
|
|
|
|
|
|
|
|
### 3.4 加载时机
|
|
|
|
|
|
|
|
|
|
|
|
在 `bootstrap.js` 启动最早期(`Bootstrap.configure()` 之前):
|
|
|
|
|
|
|
|
|
|
|
|
1. 通过 `process.execPath` 获取 exe 所在目录
|
|
|
|
|
|
2. 读取同目录下 `config.yaml`
|
|
|
|
|
|
3. 校验 schema
|
|
|
|
|
|
4. 解析后注入到 `process.env` 或全局变量
|
|
|
|
|
|
5. Midway 的 `config.prod.ts` 从该全局变量读取并覆盖默认值
|
|
|
|
|
|
|
|
|
|
|
|
### 3.5 配置优先级
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
config.yaml 外部配置 > config.prod.ts 内置默认值 > config.default.ts 基础默认值
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.6 启动顺序约束
|
|
|
|
|
|
|
|
|
|
|
|
必须严格保证初始化顺序:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
读取 config.yaml
|
|
|
|
|
|
→ 校验 config.yaml
|
|
|
|
|
|
→ 解析 dataDir
|
|
|
|
|
|
→ 初始化路径函数
|
|
|
|
|
|
→ 注册全局配置
|
|
|
|
|
|
→ 启动 Midway Bootstrap
|
|
|
|
|
|
→ 初始化各 service
|
|
|
|
|
|
→ onReady 自动开浏览器
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
任何依赖路径函数或数据库配置的模块,都不得在 `config-loader` 执行前初始化。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 安装器工具:Inno Setup
|
|
|
|
|
|
|
|
|
|
|
|
选择 Inno Setup 而非 NSIS / WiX:
|
|
|
|
|
|
- 免费开源,Windows 生态最成熟的安装器之一
|
|
|
|
|
|
- 原生支持自定义安装目录、桌面快捷方式、开机自启注册表、卸载器自动生成
|
|
|
|
|
|
- Pascal Script 可实现"选择数据目录"自定义页面
|
|
|
|
|
|
- 产物为单个 `setup.exe`,离线、自包含
|
|
|
|
|
|
- 卸载时可弹窗询问是否保留数据目录
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 安装流程(用户视角)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
双击 setup.exe
|
|
|
|
|
|
→ 欢迎页
|
2026-05-21 11:20:19 +08:00
|
|
|
|
→ 选择安装目录(默认 C:\Program Files\GPUGuard)
|
|
|
|
|
|
→ 选择数据目录(默认 C:\GPUGuardData)
|
2026-05-20 21:39:12 +08:00
|
|
|
|
→ 勾选项:
|
|
|
|
|
|
☑ 创建桌面快捷方式
|
|
|
|
|
|
☐ 开机自动启动
|
|
|
|
|
|
→ 安装进度条
|
|
|
|
|
|
→ 生成 config.yaml(写入数据目录路径)
|
|
|
|
|
|
→ 安装完成,勾选"立即启动"
|
|
|
|
|
|
→ 启动 backend.exe → 自动打开浏览器
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 卸载流程
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2026-05-21 11:20:19 +08:00
|
|
|
|
控制面板 → 卸载 GPU Guard(或运行 unins000.exe)
|
2026-05-20 21:39:12 +08:00
|
|
|
|
→ 停止正在运行的 backend.exe 进程(检查 neta.lock)
|
|
|
|
|
|
→ 弹窗:"是否同时删除本地数据?(uploads、日志、agent 存储)"
|
|
|
|
|
|
→ 是:删除数据目录
|
|
|
|
|
|
→ 否:仅删除程序目录
|
|
|
|
|
|
→ 清理桌面快捷方式、开机自启注册表项
|
|
|
|
|
|
→ 卸载完成
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 重装
|
|
|
|
|
|
|
|
|
|
|
|
- 安装器检测到已有安装 → 提示"覆盖安装"
|
|
|
|
|
|
- 覆盖程序目录,数据目录保持不动
|
|
|
|
|
|
- config.yaml 如果用户改过,保留用户版本(安装器不覆盖已存在的配置文件)
|
|
|
|
|
|
|
|
|
|
|
|
### 4.4 卸载前停止进程
|
|
|
|
|
|
|
|
|
|
|
|
Inno Setup 卸载器在删除文件前必须:
|
|
|
|
|
|
- 检查 `neta.lock` 或直接查找 `backend.exe` 进程
|
|
|
|
|
|
- 若进程仍在运行,先提示用户关闭;用户确认后可强制结束进程
|
|
|
|
|
|
- 确保 `backend.exe` 已停止后再继续删除程序目录
|
|
|
|
|
|
|
|
|
|
|
|
原因:Windows 下运行中的 exe 无法删除,且强删可能导致 SQLite / 缓存文件损坏。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.5 更新预留(不实现)
|
|
|
|
|
|
|
|
|
|
|
|
- `backend.exe --version` 输出当前版本号
|
|
|
|
|
|
- `config.yaml` 记录数据目录路径,新版安装器可读取
|
|
|
|
|
|
- 程序目录与数据目录分离本身就是更新的基础
|
|
|
|
|
|
- `bootstrap.js` 增加最小 CLI 参数解析,只支持:
|
|
|
|
|
|
- `--version`
|
|
|
|
|
|
- `--config <path>`(预留)
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 构建流水线
|
|
|
|
|
|
|
|
|
|
|
|
从源码到 `setup.exe` 的完整链路:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
[1] 构建前端 pnpm build:frontend → packages/frontend/dist/
|
|
|
|
|
|
[2] 构建后端 npm run build → packages/backend/dist/
|
|
|
|
|
|
[3] 组装 staging 合并前端产物到 public/,扁平化 node_modules
|
|
|
|
|
|
[4] Patch + Pkg patch generator-function exports → pkg → backend.exe
|
|
|
|
|
|
[5] 准备安装器素材 backend.exe + config.default.yaml + setup.iss
|
|
|
|
|
|
[6] Inno Setup 编译 iscc setup.iss → neta-setup-x.x.x.exe
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 staging 目录结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
build/pkg-stage/
|
|
|
|
|
|
├── bootstrap.js
|
|
|
|
|
|
├── dist/ ← 后端编译产物
|
|
|
|
|
|
├── public/
|
|
|
|
|
|
│ ├── index.html ← 前端产物(覆盖原欢迎页)
|
|
|
|
|
|
│ ├── static/ ← 前端 JS/CSS/资源
|
|
|
|
|
|
│ └── swagger/ ← 保留
|
|
|
|
|
|
├── typings/
|
|
|
|
|
|
├── package.json ← 精简版(flat pkg config)
|
|
|
|
|
|
└── node_modules/ ← npm install --hoisted(扁平化)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.2 自动打开浏览器
|
|
|
|
|
|
|
|
|
|
|
|
后端 `onReady` 钩子中,检测 `autoOpenBrowser: true` 且为 pkg 环境时执行:
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { exec } from 'child_process';
|
|
|
|
|
|
exec(`start http://127.0.0.1:${port}`);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 开机自启
|
|
|
|
|
|
|
|
|
|
|
|
安装器在注册表写入:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
|
2026-05-21 11:20:19 +08:00
|
|
|
|
GPUGuard = "C:\Program Files\GPUGuard\backend.exe"
|
2026-05-20 21:39:12 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
卸载时清除。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.4 已验证的 pkg 关键 patch
|
|
|
|
|
|
|
|
|
|
|
|
| 问题 | 解决方案 |
|
|
|
|
|
|
|------|----------|
|
|
|
|
|
|
| pnpm `.pnpm` 嵌套结构与 pkg 不兼容 | staging 目录用 `npm install --hoisted` 扁平化 |
|
|
|
|
|
|
| `generator-function` 的 `module-sync` 导出 `.mjs` 在 pkg 虚拟文件系统无法解析 | patch 其 `package.json` exports 回退到 CJS |
|
|
|
|
|
|
| sharp / better-sqlite3 等 native modules | 加入 pkg assets,由 pkg 运行时自动解压 |
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 运行时边界情况
|
|
|
|
|
|
|
|
|
|
|
|
### 6.1 端口冲突
|
|
|
|
|
|
|
|
|
|
|
|
启动时检测 8003 端口是否被占用,自动尝试 8004、8005...(项目已有 `availablePort` 工具函数)。
|
|
|
|
|
|
打开浏览器时使用实际绑定的端口。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 重复启动防护
|
|
|
|
|
|
|
|
|
|
|
|
在数据目录写 `neta.lock` 文件记录 PID。启动时检查该 PID 是否存活:
|
|
|
|
|
|
- 已在运行:不重复启动,直接打开浏览器访问已有实例
|
|
|
|
|
|
- 未运行:正常启动
|
|
|
|
|
|
|
|
|
|
|
|
### 6.3 日志
|
|
|
|
|
|
|
|
|
|
|
|
写入数据目录 `logs/`,按天滚动,保留最近 30 天。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.4 数据目录初始化
|
|
|
|
|
|
|
|
|
|
|
|
首次启动时自动创建所有子目录:
|
|
|
|
|
|
`uploads/`、`cache/`、`plugins/`、`skills/`、`.skillhub/`、`memory/`、`sessions/`、`logs/`
|
|
|
|
|
|
|
|
|
|
|
|
### 6.5 托盘图标(不做,预留)
|
|
|
|
|
|
|
|
|
|
|
|
第一版为控制台窗口,关闭窗口 = 停止服务。后续可加托盘最小化。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.6 数据目录位置约束
|
|
|
|
|
|
|
|
|
|
|
|
安装器在选择数据目录时需要提示:
|
2026-05-21 11:20:19 +08:00
|
|
|
|
- **推荐本地磁盘路径**(如 `D:\GPUGuardData`)
|
2026-05-20 21:39:12 +08:00
|
|
|
|
- **不推荐网络驱动器 / NAS / 可移动 U 盘**
|
|
|
|
|
|
|
|
|
|
|
|
原因:
|
|
|
|
|
|
- SQLite 的 WAL 模式在网络文件系统上不可靠,可能导致 `memory.db` / `cool.sqlite` 损坏
|
|
|
|
|
|
- 可移动磁盘在运行中拔出会导致缓存、session、上传文件写入失败
|
|
|
|
|
|
|
|
|
|
|
|
第一版不阻止用户选择网络驱动器,但需要明确警告。
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 需要改动的现有代码清单
|
|
|
|
|
|
|
|
|
|
|
|
| 文件 | 改动内容 |
|
|
|
|
|
|
|------|----------|
|
|
|
|
|
|
| `src/comm/path.ts` | 所有路径函数改为从 `resolveDataDir()` 派生,不再依赖 `process.cwd()` |
|
|
|
|
|
|
| 新增 `src/comm/data-dir.ts` | 数据目录解析:config.yaml > env > fallback |
|
|
|
|
|
|
| 新增 `src/comm/config-loader.ts` | 启动早期读取 exe 同目录下 config.yaml |
|
|
|
|
|
|
| `bootstrap.js` | 在 `Bootstrap.configure()` 前调用 config-loader |
|
|
|
|
|
|
| `src/config/config.default.ts` | staticFile.dirs 改为从 dataDir 读取 upload 路径 |
|
|
|
|
|
|
| `src/config/config.prod.ts` | 数据库连接等从外部 config.yaml 覆盖 |
|
|
|
|
|
|
| `src/modules/netaclaw/memory/sqlite_provider.ts` | `dataDir` 改为从统一配置读取 |
|
|
|
|
|
|
| `src/modules/netaclaw/session-tree/` | session 存储路径改为从统一配置读取 |
|
|
|
|
|
|
| `src/modules/netaclaw/service/skill_installer.ts` | skills 目录改为从统一配置读取 |
|
|
|
|
|
|
| `src/modules/netaclaw/service/skill_registry.ts` | `.skillhub/` 路径改为从统一配置读取 |
|
|
|
|
|
|
| `src/configuration.ts` | `onReady` 中加入自动打开浏览器逻辑 |
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 产物体积预估
|
|
|
|
|
|
|
|
|
|
|
|
| 组件 | 大小 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| backend.exe(含前端静态资源) | ~410MB |
|
|
|
|
|
|
| config.default.yaml | <1KB |
|
|
|
|
|
|
| Inno Setup 压缩后 setup.exe | ~150-200MB |
|