Skip to content

Commit c38016e

Browse files
JusterZhuclaude
andcommitted
feat: initial skill suite for GeneralUpdate integration
5 skills covering the full integration lifecycle: 1. generalupdate-init — Bootstrap config + dual-project scaffold 2. generalupdate-ui — Auto-detect UI framework, generate wired update windows with real GeneralUpdate.Core event bindings (replaces MockDownloadService) 3. generalupdate-strategy — 6 strategies: Client-Server, OSS, Silent, Differential, Cross-Version (CVP), SignalR Push 4. generalupdate-advanced — Custom hooks, strategy, Bowl crash daemon, NamedPipe IPC, and all 10+ extension points 5. generalupdate-troubleshoot — 23 symptoms from 30+ GitHub/Gitee issues All templates include detailed comments and known-issue workarounds. Co-Authored-By: Claude <noreply@anthropic.com>
0 parents  commit c38016e

36 files changed

Lines changed: 3614 additions & 0 deletions
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
name: generalupdate-advanced
3+
description: |
4+
Advanced GeneralUpdate customization: lifecycle hooks, custom strategies, Bowl crash
5+
monitoring, IPC providers, custom download/authentication, and extension management.
6+
Triggers on: "custom strategy", "custom hooks", "Bowl crash monitoring", "crash dump",
7+
"IPC named pipe", "named pipe IPC", "custom download", "custom auth provider",
8+
"extension management", "自定义策略", "Hooks", "Bowl守护", "崩溃监控",
9+
"IPC", "自定义下载", "自定义认证", "扩展管理", "插件管理".
10+
Also triggers when user mentions advanced configuration or replacement of defaults.
11+
when_to_use: |
12+
- User needs custom update lifecycle hooks (before/after update, download complete)
13+
- User wants crash monitoring and auto-restore (Bowl)
14+
- User wants to replace IPC mechanism (NamedPipe instead of encrypted file)
15+
- User needs custom authentication provider
16+
- User wants custom download executor or orchestrator
17+
- User needs custom OS strategy (replacing Windows/Linux/Mac strategy)
18+
- User asks about extension/plugin management
19+
- User already has basic integration working and wants more control
20+
allowed-tools: "Read, Write, Edit, Glob"
21+
---
22+
23+
# 🔧 GeneralUpdate 高级定制
24+
25+
提供 GeneralUpdate 全部扩展点的注入指南和代码模板。
26+
27+
## 扩展点一览
28+
29+
GeneralUpdate 提供 10+ 扩展点,可通过泛型方法注入自定义实现:
30+
31+
| 扩展方法 | 接口 | 默认实现 | 用途 |
32+
|---------|------|---------|------|
33+
| `.Hooks<T>()` | `IUpdateHooks` || 生命周期回调(更新前/后/下载完成/启动应用前) |
34+
| `.Strategy<T>()` | `IStrategy` | `WindowsStrategy` / `LinuxStrategy` / `MacStrategy` | 替换平台级更新策略 |
35+
| `.UpdateReporter<T>()` | `IUpdateReporter` | `HttpUpdateReporter` | 自定义状态上报 |
36+
| `.DownloadSource<T>()` | `IDownloadSource` | `HttpDownloadSource` | 自定义版本源 |
37+
| `.DownloadOrchestrator<T>()` | `IDownloadOrchestrator` | `DefaultDownloadOrchestrator` | 自定义下载编排 |
38+
| `.DownloadPolicy<T>()` | `IDownloadPolicy` | `DefaultRetryPolicy` | 自定义重试策略 |
39+
| `.DownloadExecutor<T>()` | `IDownloadExecutor` | `HttpDownloadExecutor` | 自定义下载执行器(如 FTP) |
40+
| `.DownloadPipeline<T>()` | `IDownloadPipeline` || 下载后处理(解密/扫描/哈希校验) |
41+
| `.SslValidationPolicy<T>()` | `ISslValidationPolicy` | `DefaultSslValidationPolicy` | 自定义 SSL 证书验证 |
42+
| `.HttpAuthProvider<T>()` | `IHttpAuthProvider` | `HmacAuthProvider` | 自定义 HTTP 认证(HMAC/Basic/Bearer/自定义) |
43+
44+
## 扩展点注入示例
45+
46+
```csharp
47+
var bootstrap = new GeneralUpdateBootstrap()
48+
.SetSource(url, key)
49+
.Hooks<MyCustomHooks>() // 自定义生命周期
50+
.UpdateReporter<MyCustomReporter>() // 自定义上报
51+
.HttpAuthProvider<MyCustomAuthProvider>() // 自定义认证
52+
.DownloadPolicy<MyCustomRetryPolicy>() // 自定义重试
53+
.SslValidationPolicy<MySslPolicy>() // 自定义 TLS 验证
54+
.SetOption(Option.AppType, AppType.Client)
55+
.LaunchAsync();
56+
```
57+
58+
## 高级功能模板
59+
60+
| 模板文件 | 功能 | 难度 |
61+
|---------|------|------|
62+
| `CustomHooks.cs` | 生命周期回调:更新前/后/下载完成/启动前 ||
63+
| `CustomStrategy.cs` | 完全替换平台更新策略 | ⭐⭐⭐ |
64+
| `BowlIntegration.cs` | 崩溃监控 + MiniDump + 自动回滚 | ⭐⭐ |
65+
| `NamedPipeIPC.cs` | 命名管道 IPC(替代加密文件) | ⭐⭐⭐ |
66+
67+
## 输出
68+
69+
根据用户的高级定制需求,输出:
70+
- ✅ 对应扩展点的接口实现代码
71+
- ✅ 注入配置代码
72+
- ✅ 注意事项和最佳实践
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# GeneralUpdate 扩展点 API 速查
2+
3+
## 注入方法调用链
4+
5+
```csharp
6+
new GeneralUpdateBootstrap()
7+
.SetSource(url, key) // 必需:服务端 API + 密钥
8+
.SetConfig(request) // 备选:完整配置(替代 SetSource)
9+
.SetOption(option, value) // 运行时选项
10+
.AddListener*(handler) // 事件监听
11+
.Hooks<T>() // 生命周期回调
12+
.Strategy<T>() // 平台策略替换
13+
.UpdateReporter<T>() // 状态上报
14+
.DownloadSource<T>() // 版本源
15+
.DownloadOrchestrator<T>() // 下载编排
16+
.DownloadPolicy<T>() // 重试策略
17+
.DownloadExecutor<T>() // 下载执行器
18+
.DownloadPipeline<T>() // 下载后处理
19+
.SslValidationPolicy<T>() // SSL 验证
20+
.HttpAuthProvider<T>() // HTTP 认证
21+
.LaunchAsync() // 执行更新
22+
```
23+
24+
## IUpdateHooks 生命周期
25+
26+
```
27+
Client 进程:
28+
OnBeforeUpdateAsync() → 返回 false 中止更新
29+
OnDownloadCompletedAsync() → 所有包下载完成
30+
→ 启动 Upgrade 进程
31+
32+
Upgrade 进程:
33+
OnBeforeUpdateAsync() → 返回 false 中止更新
34+
→ 执行管道(Hash→解压→Patch)
35+
OnAfterUpdateAsync() → 更新完成
36+
OnBeforeStartAppAsync() → 返回 false 阻止启动
37+
→ 启动主应用
38+
39+
任意进程出错时:
40+
OnUpdateErrorAsync() → 错误处理
41+
```
42+
43+
## SSL 验证策略
44+
45+
```csharp
46+
// 默认:系统默认证书验证
47+
public class DefaultSslValidationPolicy : ISslValidationPolicy
48+
{
49+
public bool ValidateServerCertificate(
50+
object sender, X509Certificate? certificate,
51+
X509Chain? chain, SslPolicyErrors sslPolicyErrors)
52+
=> sslPolicyErrors == SslPolicyErrors.None;
53+
}
54+
```
55+
56+
## HTTP 认证提供者
57+
58+
| 提供者 | 实现 | 适用场景 |
59+
|--------|------|---------|
60+
| `HmacAuthProvider` | HMAC-SHA256 Header | GeneralSpacestation 默认 |
61+
| `BasicAuthProvider` | Basic Auth Header | 企业内网 |
62+
| `BearerAuthProvider` | Bearer Token | OAuth / JWT |
63+
| 自定义 | 实现 `IHttpAuthProvider` | 任意认证方案 |
64+
65+
## Bowl 选项
66+
67+
| 选项 | 类型 | 默认值 | 说明 |
68+
|------|------|--------|------|
69+
| `TargetAppPath` | string || 被监控的主应用路径 |
70+
| `InstallPath` | string || 安装目录 |
71+
| `AutoRestore` | bool | false | 崩溃时自动回滚备份 |
72+
| `ReportOutputPath` | string | `CrashReports/` | 崩溃报告输出目录 |
73+
74+
## Bowl 崩溃生命周期
75+
76+
```
77+
Upgrade 进程完成更新
78+
→ 调用 StartAppAsync
79+
→ 启动主应用
80+
→ (可选) 启动 Bowl 守护进程
81+
→ Bowl Phase 1: 准备 procdump 监控
82+
→ Bowl Phase 2: 运行监控子进程
83+
→ Bowl Phase 3: 检查 dump 文件
84+
→ Bowl Phase 4 (崩溃):
85+
→ 生成 MiniDump
86+
→ 写入 CrashReport.json
87+
→ 自动回滚(如配置)
88+
→ 导出系统诊断信息
89+
→ 触发 OnCrash 回调
90+
```
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using GeneralUpdate.Bowl;
2+
using GeneralUpdate.Core.Models;
3+
4+
/// <summary>
5+
/// 【Skill 自动生成】Bowl 崩溃守护集成
6+
///
7+
/// Bowl 是一个跨平台的崩溃监控助手,在升级完成后监控主应用的启动情况。
8+
/// 如果主应用崩溃,Bowl 会:
9+
/// 1. 生成 MiniDump 文件
10+
/// 2. 写入 CrashReport.json(崩溃诊断报告)
11+
/// 3. 可选:从备份自动回滚
12+
/// 4. 触发 OnCrash 回调
13+
///
14+
/// 使用方式:
15+
/// 在 Upgrade 完成后启动 Bowl(由 StartAppAsync 自动处理)
16+
/// 或者在主应用启动后手动调用 Bowl.LaunchAsync()
17+
///
18+
/// NuGet: dotnet add package GeneralUpdate.Bowl
19+
///
20+
/// ⚠️ 注意事项:
21+
/// 1. Bowl 目前仅在 Windows 上充分测试
22+
/// 2. 回滚依赖于更新前的备份(BackupEnabled = true)
23+
/// 3. 备份保留最多 3 个版本
24+
/// 4. Bowl 需要使用 procdump 工具(Windows)
25+
/// </summary>
26+
public static class BowlIntegration
27+
{
28+
/// <summary>
29+
/// 启动 Bowl 崩溃守护
30+
/// </summary>
31+
public static async Task StartBowlAsync(string appPath, string installPath)
32+
{
33+
Console.WriteLine("[Bowl] 启动崩溃守护进程...");
34+
35+
var bowl = new Bowl();
36+
37+
// 注册崩溃回调
38+
bowl.OnCrash += (crashReport) =>
39+
{
40+
Console.WriteLine($"[Bowl] 检测到崩溃!");
41+
Console.WriteLine($"[Bowl] 原因: {crashReport.CrashReason}");
42+
Console.WriteLine($"[Bowl] Dump 文件: {crashReport.DumpFilePath}");
43+
44+
// 自动回滚(前提是有备份)
45+
if (crashReport.AutoRestore)
46+
{
47+
Console.WriteLine("[Bowl] 正在回滚到备份版本...");
48+
// Bowl 会自动从备份目录恢复
49+
}
50+
};
51+
52+
// 启动监控
53+
await bowl.LaunchAsync(new BowlOptions
54+
{
55+
// 要监控的主应用路径
56+
TargetAppPath = appPath,
57+
// 安装目录(用于定位备份)
58+
InstallPath = installPath,
59+
// 启用自动回滚
60+
AutoRestore = true,
61+
// 崩溃报告输出目录
62+
ReportOutputPath = Path.Combine(
63+
installPath, "CrashReports")
64+
});
65+
}
66+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using GeneralUpdate.Core.Hooks;
2+
using GeneralUpdate.Core.Models;
3+
4+
/// <summary>
5+
/// 【Skill 自动生成】自定义生命周期 Hooks
6+
///
7+
/// 实现 IUpdateHooks 接口,在更新的各个生命周期阶段插入自定义逻辑。
8+
/// 所有方法都有默认实现(返回 null/true),只需重写需要的方法。
9+
///
10+
/// 使用方式:
11+
/// .Hooks<MyCustomHooks>()
12+
/// </summary>
13+
public class MyCustomHooks : IUpdateHooks
14+
{
15+
/// <summary>
16+
/// 更新开始前调用。返回 false 中止更新。
17+
/// 可用于:检查磁盘空间、检查是否在营业时间、用户确认等。
18+
/// </summary>
19+
public async Task<bool> OnBeforeUpdateAsync(UpdateContext context)
20+
{
21+
Console.WriteLine($"[Hooks] 开始更新: {context.CurrentVersion}{context.LastVersion}");
22+
23+
// 检查磁盘空间
24+
var drive = new DriveInfo(Path.GetPathRoot(context.InstallPath)!);
25+
if (drive.AvailableFreeSpace < 100 * 1024 * 1024) // 100MB 最低要求
26+
{
27+
Console.WriteLine("[Hooks] 磁盘空间不足,中止更新");
28+
return false;
29+
}
30+
31+
return true; // true = 继续更新
32+
}
33+
34+
/// <summary>
35+
/// 下载完成后调用(在 Client 进程)
36+
/// 可用于:下载后扫描、日志记录、通知 UI
37+
/// </summary>
38+
public async Task OnDownloadCompletedAsync(UpdateContext context)
39+
{
40+
Console.WriteLine($"[Hooks] 下载完成: {context.LastVersion}");
41+
// 可以在这里触发 UI 通知
42+
await Task.CompletedTask;
43+
}
44+
45+
/// <summary>
46+
/// 更新完成后调用(在 Upgrade 进程,替换文件后)
47+
/// 可用于:清理临时文件、更新数据库 schema、迁移用户配置
48+
/// </summary>
49+
public async Task OnAfterUpdateAsync(UpdateContext context)
50+
{
51+
Console.WriteLine($"[Hooks] 更新完成: {context.LastVersion}");
52+
53+
// 清理临时文件
54+
var tempDir = context.UpdatePath;
55+
if (Directory.Exists(tempDir))
56+
{
57+
try { Directory.Delete(tempDir, true); }
58+
catch { /* 忽略清理中的错误 */ }
59+
}
60+
61+
await Task.CompletedTask;
62+
}
63+
64+
/// <summary>
65+
/// 更新过程出错时调用
66+
/// 可用于:错误日志、通知管理员、触发回滚
67+
/// </summary>
68+
public async Task OnUpdateErrorAsync(UpdateContext context, Exception exception)
69+
{
70+
Console.WriteLine($"[Hooks] 更新失败: {exception.Message}");
71+
// 记录错误日志
72+
File.WriteAllText(
73+
Path.Combine(context.InstallPath, "update_error.log"),
74+
$"[{DateTime.UtcNow}] {exception}");
75+
await Task.CompletedTask;
76+
}
77+
78+
/// <summary>
79+
/// 启动主应用前调用(在 Upgrade 进程)
80+
/// 可用于:修改配置文件、设置环境变量、检查版本兼容性
81+
/// 返回 false 阻止主应用启动
82+
/// </summary>
83+
public async Task<bool> OnBeforeStartAppAsync(UpdateContext context)
84+
{
85+
Console.WriteLine($"[Hooks] 准备启动主应用: {context.MainAppName}");
86+
87+
// 在 Linux/MacOS 上设置可执行权限
88+
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
89+
{
90+
var appPath = Path.Combine(context.InstallPath, context.MainAppName ?? "");
91+
if (File.Exists(appPath))
92+
{
93+
await UnixPermissionHooks.SetExecutablePermissionAsync(appPath);
94+
}
95+
}
96+
97+
return true; // true = 启动主应用
98+
}
99+
}

0 commit comments

Comments
 (0)