# 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 管理页能读到内置 skill,Tool 管理页能读到工具 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 安装器实现后的真实状态**,不是目标态说明。后续若补齐托盘、自动更新、安装器数据目录选择等能力,需要同步更新本文件。