跳到主要内容

🩺 GeneralUpdate 故障排查

综合性诊断系统 — 覆盖 50+ 已知问题,均可追溯到 GitHub/Gitee Issue 或代码审计发现。


📋 用户症状提取

### 必填信息
- 症状描述: ______
- 错误信息/堆栈: ______
- GeneralUpdate 版本: ______
- 平台: ______(Windows / Linux / macOS)
- .NET 版本: ______
- 更新策略: ______(标准 / OSS / 静默 / 差分 / 跨版本 / 推送)
- 最近是否改过配置: ______(是/否,改了啥)

### 可选信息
- 事件监听中是否有异常(ExceptionEventArgs): ______
- 是否有日志(Logs/generalupdate-trace-*.log): ______
- 问题是否可复现: ______(是/否,频率)
- 首次出现时间点: ______

工作流程

1. 症状收集
├── 用户描述的症状是什么?
├── 错误信息/堆栈是什么?
├── GeneralUpdate 版本号?
├── 平台(Windows/Linux/macOS)?
└── 更新策略(标准/OSS/静默)?

2. 症状匹配
├── 优先:python3 scripts/search.py "<症状>" --domain issue
│ └── 匹配到 → 给出根因 + 修复 + 代码
└── 未匹配 → 降级到 reference.md 全文搜索

3. 提供修复
├── 具体的代码修改、配置调整、版本升级建议
└── 预防措施(如何避免再发生)

4. 验证
└── 确认修复后问题解决

症状搜索(推荐)

优先使用 BM25 搜索引擎精确匹配已知问题,而不是在 reference.md 中手动查找:

# 自然语言搜索已知问题
python3 .claude/skills/generalupdate-troubleshoot/scripts/search.py "升级后应用启动不了" --domain issue
python3 .claude/skills/generalupdate-troubleshoot/scripts/search.py "方法找不到 MethodNotFound" --domain issue
python3 .claude/skills/generalupdate-troubleshoot/scripts/search.py "中文乱码 garbled" --domain issue

# 搜索策略相关问题
python3 .claude/skills/generalupdate-troubleshoot/scripts/search.py "OSS 权限问题" --domain strategy

症状分级

reference.md 中的问题按严重度分级:

级别颜色含义数量
C🔴 致命阻断性故障、数据损坏、安全漏洞8
H🟠 场景阻断、功能失效、需要升级11
M🟡 功能异常、需要配置调整20
L🔵 代码气味、边缘情况、已知行为12

完整清单请查阅 reference.md


✅ 通用诊断前检查清单

运行环境检查

  • 目标机器安装了正确的 .NET 运行时(版本与发布框架匹配)
  • 目标机器上有写入权限(InstallPath 目录可写)
  • 防火墙未阻断 UpdateUrl 的通信端口
  • 磁盘空间充足(至少 2× 更新包大小)
  • Linux/macOS:UpgradeApp 有 chmod +x 执行权限

版本检查

  • Client 和 Upgrade 项目 NuGet 版本完全一致
  • 服务端返回的版本号是 4 段式(如 1.0.0.0)
  • manifest.json 中 mainAppName 与实际进程名匹配
  • AppType 设置正确(Client = 1, Upgrade = 2)

配置检查

  • UpdateRequest 的 6 个必填字段都已设置
  • UpdateUrl 可通过 HTTP GET 访问并返回合法 JSON
  • AppSecretKey 与服务端配置一致(长度 ≥ 16 字符)
  • UpgradeApp.exe 存在于发布目录的 update/ 子目录中

日志检查

  • 查看 Logs/generalupdate-trace-*.log(如有)
  • 检查事件监听中的 ExceptionEventArgs
  • 检查 MultiDownloadErrorEventArgs 中的异常

C 级(Critical)— 阻塞升级

问题原因排查/解决
升级没启动LaunchAsync() 未调用 / UpgradeApp.exe 未部署确认 Bootstrap.LaunchAsync()Main() 中调用
Method not foundClient 和 Upgrade NuGet 版本不一致统一 NuGet 版本, 清理 bin/obj 后重新生成
路径超长 (>260)Windows 路径限制缩短安装路径
IPC 暴露IPC 加密密钥硬编码使用强 AppSecretKey; 更新到 v10.4.6+
跨租户泄露服务端多租户隔离缺失每个租户独立 ProductId + AppSecretKey
ZIP 遍历写入恶意 ZIP 含 ../ 路径v10.4.6+ 已修复
BSDIFF 整数溢出大文件差分补丁计算溢出使用 HDiffPatch 算法
静默不生效进程退出时未触发确保正确调用 Close() 或 Dispose()

H 级(High)— 严重但不阻塞启动

问题原因排查/解决
无限循环更新manifest.json 版本号未回写更新到 v10.4.6+(已修复 WriteBack)
OSS 无更新Bucket 配置错误 / versions.json 格式不对curl 测试 OSS URL 是否可下载
文件占用目标文件被占用关闭主进程后更新; 排除杀软扫描目录
SignalR 推送无响应连接断开或认证失败检查 SignalR Hub 状态和 Token 配置
Bowl 不守护进程名配置错误确认 ProcessNameOrId 与实际进程名一致
差分更新失败基准文件不匹配校验原始文件哈希匹配
下载进度不动IDownloadService 未正确绑定确认桥接实现是否正确
跨版本跳跃失败中间版本包缺失确保服务端保留了所有版本的补丁

M 级(Medium)— 功能降级

问题原因排查/解决
AOT 编译失败反射代码未适配 NativeAOT添加 [DynamicDependency] 属性
SignalR 重连慢RetryDelay 配置过长调整重连参数
日志不输出日志路径权限不足检查 %TEMP%/GeneralUpdate/logs/ 权限
多租户配置错误ProductId 冲突确保每个租户唯一 ProductId
黑名单不生效格式配置错误确认文件名和扩展名格式正确

L 级(Low)— 非关键

问题原因排查/解决
分发包过大未使用差分差分已内嵌在 Core,启用 PatchEnabled 即可
首次更新慢CDN 冷启动预热 CDN
更新后配置丢失黑名单未包含配置目录确认 Directories 包含配置文件夹

通用诊断流程(6 步)

当问题无法直接匹配到已知症状时,执行以下 6 步排查:

  1. 版本一致性检查 — Client 和 Upgrade 的 NuGet 版本是否一致?
  2. manifest.json 验证 — 文件是否存在?字段值是否正确?
  3. UpgradeApp 存在性 — UpgradeApp.exe 是否在预期目录?
  4. 网络可访问性 — UpdateUrl 能否用 curl 访问?
  5. 日志分析 — 查看 Logs/generalupdate-trace-*.log 下的日志文件
  6. 最小重现 — 从 Minimal 集成开始,逐步增加复杂度

日志文件位置

平台默认路径
Windows%TEMP%/GeneralUpdate/logs/
Linux/tmp/GeneralUpdate/logs/

安全注意事项

  • AppSecretKey 管理 — 硬编码在客户端是最后手段; 优先从启动参数或环境变量注入
  • 定期轮换 IPC 加密密钥
  • 生产环境禁用调试日志

⚠️ 诊断阶段的反模式

#反模式后果正确做法
1只看错误信息不看事件错过 ExceptionEventArgs 中的详细信息订阅所有 7 个事件
2日志文件路径不对就认为无日志漏掉关键诊断信息在 InstallPath/Logs 下查找
3只检查 Client 不检查 Upgrade 进程问题在 Upgrade 端但诊断方向全错两端都要检查
4升级问题直接改代码可能是服务端配置问题而非客户端 Bug优先检查服务端返回的版本信息
5忽略 NuGet 版本一致性方向错,"Method not found" 根因是版本不一致第一个就要检查版本
6只在 Debug 环境测试Release 环境可能缺少运行时文件在发布/生产环境复现

相关技能

  • /generalupdate-init — Bootstrap 配置
  • /generalupdate-ui — 更新界面诊断
  • /generalupdate-strategy — 策略相关故障
  • /generalupdate-advanced — 高级功能故障