# Windows 服务状态管理功能 — 上线/回滚文档 **分支**: `feat/windows-service-status-auto` **目标**: `main` **日期**: 2026-05-04 **PR URL**: https://git.cjy.net.cn/jcl/haoliang-net/compare/main...feat/windows-service-status-auto --- ## 一、功能概述 为 CncCollector 采集服务添加原生 Windows Service 支持,实现双模式运行(控制台调试 + Windows 服务),并在管理后台仪表盘准确展示服务运行状态(未安装/运行中/启动中/启动失败/已停止),支持远程启动/停止操作。 ## 二、变更清单 ### 2.1 后端变更 | 文件 | 变更类型 | 说明 | |------|----------|------| | `src/CncCollector/CncCollectorService.cs` | 新增 | ServiceBase 包装,OnStart/OnStop/OnPause/OnContinue/OnShutdown | | `src/CncCollector/ProjectInstaller.cs` | 新增 | InstallUtil 安装器配置 | | `src/CncCollector/Program.cs` | 修改 | 双模式入口(--console 调试/无参数=服务模式/--install/--uninstall) | | `src/CncCollector/CncCollector.csproj` | 修改 | 添加 System.ServiceProcess + System.Configuration.Install 引用 | | `src/CncService/Interface/IWindowsServiceChecker.cs` | 新增 | 服务状态检测接口 + ServiceStatusEnum 枚举 | | `src/CncService/Impl/WindowsServiceChecker.cs` | 新增 | 基于 ServiceController 的实现 | | `src/CncService/Impl/DashboardService.cs` | 修改 | 注入 IWindowsServiceChecker,增强 GetCollectorStatus 返回 serviceStatus/serviceName/serviceMessage | | `src/CncWebApi/Controllers/DashboardController.cs` | 修改 | StartCollector 前置状态检查(NotInstalled→40001, Running→40002) | | `src/CncWebApi/Infrastructure/ServiceResolver.cs` | 修改 | DI 注入 WindowsServiceChecker | | `src/CncCollector/scripts/install.ps1` | 新增 | 安装脚本 v2.0(InstallUtil/NSSM/SC 三级降级) | | `src/CncCollector/scripts/uninstall.ps1` | 新增 | 卸载脚本 v2.0(三级降级卸载 + 交互式清理) | ### 2.2 前端变更 | 文件 | 变更类型 | 说明 | |------|----------|------| | `frontend/src/types/index.ts` | 修改 | CollectorStatus 接口扩展 serviceStatus/serviceName/serviceMessage 字段 | | `frontend/src/views/dashboard/DashboardPage.vue` | 修改 | 服务状态标签映射、未安装引导提示、启动按钮逻辑 | ### 2.3 测试变更 | 文件 | 变更类型 | 说明 | |------|----------|------| | `tests/CncService.Tests/WindowsServiceCheckerTests.cs` | 新增 | 服务检测单元测试(2 个用例) | | `tests/CncService.Tests/DashboardServiceTests.cs` | 新增 | DI 场景测试(3 个用例:NotInstalled/Running/Starting) | ### 2.4 CI/CD 变更 | 文件 | 变更类型 | 说明 | |------|----------|------| | `.github/workflows/ci-windows.yml` | 新增 | Windows CI 流水线(构建 + 测试 + 前端构建) | ## 三、错误码定义 | 错误码 | 含义 | 触发条件 | |--------|------|----------| | 40001 | 服务未安装 | Windows 中不存在 CncCollector 服务 | | 40002 | 服务已在运行 | 服务当前状态为 Running | | 50002 | 服务启动失败 | 启动操作超时或返回错误 | | 50003 | 服务不可用 | 服务状态异常 | ## 四、验证结果 ### 4.1 编译验证 | 项目 | 结果 | 备注 | |------|------|------| | dotnet build(全解决方案) | ✅ 0 错误 | 82 个 CS1591 警告(既有 XML 注释缺失) | | npm run build(前端) | ✅ 0 错误 | vue-tsc 类型检查 + vite 构建通过 | ### 4.2 单元测试 | 测试用例 | 结果 | |----------|------| | `WindowsServiceCheckerTests.GetServiceStatus_NotInstalled_ForUnknownService` | ✅ 通过 | | `WindowsServiceCheckerTests.TryStartService_NotInstalled_ReturnsNotInstalled` | ✅ 通过 | | `DashboardServiceTests.GetCollectorStatus_With_NotInstalled_Service_Returns_NotInstalled_State` | ✅ 通过 | | `DashboardServiceTests.GetCollectorStatus_With_Running_Heartbeats_Returns_Running_State` | ✅ 通过 | | `DashboardServiceTests.GetCollectorStatus_With_Starting_ServiceStatus_Returns_Starting_State` | ✅ 通过 | **5/5 测试全部通过。** 注:其他 55 个失败的测试为既有数据库外键约束问题,与本次改动无关。 ## 五、上线步骤 ### 5.1 前置条件 - 服务器:192.168.1.202(Windows Server) - MariaDB 11.8 已运行 - IIS 应用池 `haoliang` 已配置 - 当前 CncCollector 以控制台模式运行(需停掉) ### 5.2 上线流程 ```powershell # 1. 合并分支到 main git checkout main git merge feat/windows-service-status-auto git push # 2. 构建后端 dotnet build -c Release # 3. 构建前端 cd frontend npm ci npm run build cd .. # 4. 部署 Web API 到 IIS # 复制 src/CncWebApi/bin/Release 到 C:\inetpub\wwwroot\haoliang # 复制 frontend/dist 到 C:\inetpub\wwwroot\haoliang\admin Import-Module WebAdministration Restart-WebAppPool -Name 'haoliang' # 5. 停掉当前控制台模式的 CncCollector(如有) # 任务管理器结束 CncCollector.exe 进程 # 6. 安装为 Windows 服务 cd src/CncCollector/scripts .\install.ps1 # 7. 验证服务状态 Get-Service CncCollector # 应显示 Status=Running # 8. 验证管理后台仪表盘 # 浏览器打开 http://192.168.1.202/admin/ # 查看首页采集服务状态卡片,应显示"运行中" ``` ### 5.3 验证清单 - [ ] 管理后台仪表盘服务状态显示正确 - [ ] 服务未安装时显示"未安装"并提供安装引导 - [ ] 启动按钮可远程启动服务 - [ ] 停止按钮可远程停止服务 - [ ] 服务状态实时刷新(30秒心跳) - [ ] 安装脚本 install.ps1 正常工作 - [ ] 卸载脚本 uninstall.ps1 正常工作 ## 六、回滚方案 ### 6.1 回滚触发条件 - 服务安装失败无法启动 - 管理后台仪表盘状态显示异常 - 采集数据丢失或中断超过 10 分钟 ### 6.2 回滚步骤 ```powershell # 1. 卸载 Windows 服务 cd src/CncCollector/scripts .\uninstall.ps1 # 2. 回退代码到上一个稳定版本 git checkout main git revert HEAD # 回退本次合并 git push # 3. 重新部署旧版 Web API # 从备份恢复 IIS 目录 Import-Module WebAdministration Restart-WebAppPool -Name 'haoliang' # 4. 恢复控制台模式运行 # 用旧版 CncCollector.exe 以控制台模式启动 Start-Process -FilePath "C:\path\to\CncCollector.exe" -ArgumentList "--console" ``` ### 6.3 回滚注意事项 - 卸载服务前先停止服务 - 数据库无 schema 变更,无需回滚数据库 - 前端回滚随 IIS 部署自动恢复 - 回滚后确认采集数据恢复正常 ## 七、风险评估 | 风险项 | 级别 | 应对措施 | |--------|------|----------| | Windows 服务权限不足 | 低 | install.ps1 自动请求管理员权限 | | 服务安装失败 | 中 | 提供三级降级安装策略(InstallUtil→NSSM→SC) | | 心跳超时误判 | 低 | 超时阈值设为 90 秒(3个心跳间隔) | | 服务启动超时 | 中 | TryStartService 默认等待 30 秒,可配置 | | 前端类型错误 | 已修复 | CollectorStatus 接口合并、serviceStatusLabel 移入 script setup | ## 八、提交记录 | 提交 | 说明 | |------|------| | `6e5b296` | 增加 Windows Service 原生支持,双模式运行和服务安装卸载 | | `9e3a759` | 修复仪表盘采集服务状态判断:增加心跳超时检测 | | `e9802a1` | 前端适配、后端测试扩展、CI/Playwright E2E | | `d8f5925` | 扩展 DashboardServiceTests DI 场景 | | `0212ed6` | CI 工作流和扩展测试 | | `acdc502` | 新增 Starting 状态测试用例 | | (待提交) | 修复前端类型错误 + CI 配置修复 |