2026-05-20 21:39:12 +08:00

360 lines
9.3 KiB
Markdown
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.

# Neta Backend / Windows 安装器打包说明
本文档记录当前 Windows 离线安装器的打包方式、依赖要求、产物路径,以及当前版本仍然存在的缺口。
## 当前状态
当前已经可以产出以下三个文件:
- `build/pkg-output/backend.exe`
- `build/tray-output/Neta.Tray.exe`
- `build/installer-output/neta-setup.exe`
其中:
- `backend.exe` 是前端静态资源 + 后端 Midway.js + Node.js 运行时的单文件产物
- `Neta.Tray.exe` 是 Windows 托盘控制层产物
- `neta-setup.exe` 是基于 Inno Setup 的离线安装器
- `packages/backend/skills` 会随安装器一起打包,并在首次启动时同步到数据目录的 `skills/`
## 打包环境要求
建议在 **Windows 10/11 x64** 上打包。
需要提前安装:
### 1. Node.js
建议使用当前项目已验证版本范围内的 Node.js建议 20+,当前环境也已在 Node 22 下完成打包验证)。
### 2. pnpm
前端构建使用 `pnpm build`
安装示例:
```bash
npm install -g pnpm
```
### 3. .NET 8 SDK
生成 `tray.exe` 需要安装 .NET 8 SDK。
```bash
winget install Microsoft.DotNet.SDK.8
```
### 4. Inno Setup 6
生成 `neta-setup.exe` 需要安装 Inno Setup 6。
可使用:
```bash
winget install --id JRSoftware.InnoSetup --accept-package-agreements --accept-source-agreements
```
当前脚本会自动尝试从以下位置查找 `ISCC.exe`
- `%LOCALAPPDATA%\Programs\Inno Setup 6\ISCC.exe`
- `C:\Program Files (x86)\Inno Setup 6\ISCC.exe`
- `C:\Program Files\Inno Setup 6\ISCC.exe`
- 或系统 PATH 中的 `iscc`
## 一键打包步骤
### 方式一:先打 exe再打安装器
`packages/backend` 目录执行:
```bash
npm run pkg
node scripts/build-windows-installer.js
```
### 方式二:直接打安装器
```bash
npm run build:windows-installer
```
说明:
- `build-windows-installer.js` 会先检查 `build/pkg-output/backend.exe`
- 如果不存在,会自动先执行 `scripts/pkg-build.js`
- 然后执行 `dotnet publish` 生成 `build/tray-output/Neta.Tray.exe`
- 最后由 Inno Setup 生成安装器,并把 `packages/backend/skills` 一并带入安装目录
## 当前打包脚本做了什么
### `scripts/pkg-build.js`
执行顺序如下:
1. 构建前端
2. 构建后端
3. 生成 `build/pkg-stage/` staging 目录
4. 把前端产物覆盖到后端 `public/`
5. 生成 staging 用的 `package.json`
6. 用 npm 在 staging 目录做扁平化生产依赖安装
7. patch `generator-function` 的 exports规避 pkg 对 `.mjs` 的兼容问题
8. 执行 `@yao-pkg/pkg` 生成 `backend.exe`
### installer 构建时的前端特殊处理
Windows 安装器构建不是普通线上前端构建,当前脚本会额外注入:
- `VITE_API_BASE_URL=''`
- `VITE_COOL_EPS_ENABLE=true`
这样做的原因:
1. 安装器场景下前后端同源运行,前端 API 需要走本地同源地址
2. installer 场景前端仍依赖构建期生成的 EPS service 代理;若关闭,会导致 `service.base.open` 不存在,从而在登录页初始化时报错
## 产物位置
打包完成后产物位于:
```text
packages/backend/build/pkg-output/backend.exe
packages/backend/build/tray-output/Neta.Tray.exe
packages/backend/build/installer-output/neta-setup.exe
```
## 当前安装器默认行为
### 安装目录
默认安装到:
```text
C:\Program Files\Neta
```
### 当前默认配置文件
安装器会把:
```text
installer/config.default.yaml
```
复制为安装目录下的:
```text
config.yaml
```
### 当前数据目录
当前默认写死为:
```text
C:\NetaData
```
运行数据日志、lock、runtime-info、skills都写到这里。
### 内置 Skill 目录
安装器会把:
```text
packages/backend/skills
```
打进安装目录下的:
```text
{app}\skills
```
并在首次启动时把缺失的内置 skill 同步到:
```text
C:\NetaData\skills
```
本地开发(`npm run dev`)仍直接读取仓库内的:
```text
packages/backend/skills
```
### 桌面快捷方式
安装器会创建桌面快捷方式和开始菜单快捷方式,启动 `tray.exe`,由托盘控制层负责附着或拉起 `backend.exe`
## 当前已知缺口 / 发布前建议补齐项
以下问题目前都已经记录,**其中部分属于发布阻塞项**。
### 1. 数据库账号密码仍然是明文配置(发布阻塞)
当前 `installer/config.default.yaml` 里包含数据库连接信息,安装后会以明文形式写到安装目录下的 `config.yaml`
当前风险:
- 用户机器上可直接看到数据库账号密码
- 安装目录中的配置文件容易被误拷贝、误传播
- 不适合正式对外发布
建议后续方案:
- 安装器安装时让用户输入数据库连接信息
- 或首次启动时通过配置向导填写
- 或改为读取更安全的部署侧配置(如企业内部分发配置)
- 至少不要把正式生产数据库凭证直接内置到默认配置模板中
### 2. 当前没有自动更新机制
当前安装器只支持重新打包、重新安装,不支持:
- 在线检查更新
- 增量更新
- 回滚
- 版本迁移提示
建议后续补齐:
- 版本检查
- 升级包下载
- 升级失败回滚
- 配置/数据迁移策略
### 3. Windows 托盘模式
当前安装器已切换为 `tray.exe` 作为用户入口:
- 桌面快捷方式与开始菜单快捷方式指向 `tray.exe`
- 托盘菜单提供“打开系统 / 重启服务 / 停止服务 / 打开日志目录 / 打开配置目录 / 退出程序”
- 托盘优先通过 `runtime-info.json` + 本机 `status/stop` 控制面附着已运行后端
- “打开系统”始终使用 runtime 状态接口返回的真实 URL因此当 8003 被占用、后端回退到 8004/8005 等端口时,托盘会打开实际运行端口
- 停止服务 / 退出程序 / 卸载都会先尝试优雅停机,再按安装目录路径兜底清理残留 `backend.exe`
### 4. 当前关闭路径
当前停机 / 卸载路径为:
```text
停止服务 / 退出程序
└─ 优先调用 /app/base/runtime/stop
└─ 等待 backend 退出
└─ 若仍存活,则按安装目录路径强杀所有 backend.exe
卸载
└─ tray.exe --shutdown
└─ taskkill /IM tray.exe /F
└─ taskkill /IM backend.exe /F
```
也就是说:
- 优先走托盘触发的本机优雅停机
- 如果 `runtime-info.json` 丢失、stop 接口失败、或 pkg stub / wrapper 残留,仍会按安装目录路径兜底清理 backend 进程
- “退出程序”不只是退出托盘,也会先结束后台服务
### 5. 安装器还没有“数据目录选择页”
设计文档中原本计划支持用户选择数据目录,但当前实现仍然使用默认值:
```text
C:\NetaData
```
也就是说:
- 目前用户可以选程序安装目录
- 但不能在安装器 UI 中选择数据目录
- `config.yaml` 中的数据目录还没有在安装时动态写入
这也是当前版本与设计目标之间的重要差距之一。
### 6. 缺少首次启动配置向导 / 数据库连通性检测
当前安装后直接启动,如果配置不对,只能从日志或错误提示中排查。
建议后续补齐:
- 首次启动向导
- 数据库连接测试
- 数据目录可写性测试
- 端口占用检查提示
### 7. 升级迁移策略还不完整
当前虽然已经做到“程序目录 / 数据目录分离”,但还缺少:
- `config.yaml` schema 版本迁移
- 数据目录结构升级迁移
- 不同版本安装器对旧配置的兼容检查
### 8. 当前更偏向“内测版安装器”,还不适合作为正式商用发布版
当前版本已经可用于:
- 内部验证
- 本地演示
- 离线安装链路测试
但如果要进入正式对外发布,还建议至少补齐:
- 配置安全
- 托盘/服务控制
- 数据目录选择
- 升级更新
- 更友好的故障提示和日志查看入口
## 推荐的下一阶段改造优先级
建议按下面顺序推进:
1. **去掉明文数据库凭证**
2. **实现安装器数据目录选择 + 写回 config.yaml**
3. ~~增加 Windows 托盘控制入口~~ ✅ 已完成
4. ~~实现优雅停止服务~~ ✅ 已完成
5. **补自动更新机制**
## 验证命令
重新打包后,可用以下命令验证:
```bash
cd packages/backend
npm run build:windows-installer
```
验证产物:
```bash
ls -lh build/pkg-output/backend.exe
ls -lh build/tray-output/Neta.Tray.exe
ls -lh build/installer-output/neta-setup.exe
```
### Windows 托盘模式验证
验证点:
- `tray.exe` 能读取 `config.yaml``runtime-info.json`
- 托盘能附着或拉起 `backend.exe`
- “打开系统”使用 runtime 状态接口返回的真实 URL包括 8003 被占用时的回退端口)
- 内置 skill 会从安装目录 `skills/` 同步到数据目录 `skills/`
- Skill 管理页能读到内置 skillTool 管理页能读到工具 catalog
- “停止服务”能让 backend 退出;再次“打开系统”后托盘状态会恢复为“运行中”
- “退出程序”会先结束 backend再退出 tray
- 卸载时优先调用 `tray.exe --shutdown`
- 若优雅停机失败,仍会兜底清理安装目录对应的 `backend.exe`
如果只验证 exe
```bash
cp installer/config.default.yaml build/pkg-output/config.yaml
build/pkg-output/backend.exe
```
## 备注
当前 README 记录的是 **截至本次 Windows 安装器实现后的真实状态**,不是目标态说明。后续若补齐托盘、自动更新、安装器数据目录选择等能力,需要同步更新本文件。