diff --git a/website/docs/doc/GeneralUpdate.Bowl.md b/website/docs/doc/GeneralUpdate.Bowl.md index d490a12..5925874 100644 --- a/website/docs/doc/GeneralUpdate.Bowl.md +++ b/website/docs/doc/GeneralUpdate.Bowl.md @@ -417,4 +417,4 @@ MyApp/ - [Bowl 示例代码](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Bowl) - [GeneralUpdate 仓库](https://github.com/GeneralLibrary/GeneralUpdate) -- [Dump 指南](../guide/Dump) +- [Dump 指南](../guide/Deployment and Operations) diff --git a/website/docs/doc/GeneralUpdate.Differential.md b/website/docs/doc/GeneralUpdate.Differential.md index 7613c1f..847a6ea 100644 --- a/website/docs/doc/GeneralUpdate.Differential.md +++ b/website/docs/doc/GeneralUpdate.Differential.md @@ -364,4 +364,4 @@ await new GeneralUpdateBootstrap() - [GeneralUpdate 仓库](https://github.com/GeneralLibrary/GeneralUpdate) - [Samples 差分示例](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Hub/Samples/DifferentialSample.cs) - [Core DiffPipeline 文档](GeneralUpdate.Core) -- [Tools 打包指南](../guide/Packaging) +- [Tools 打包指南](../guide/Deployment and Operations) diff --git a/website/docs/doc/GeneralUpdate.Extension.md b/website/docs/doc/GeneralUpdate.Extension.md index 81e048a..3b3c4a3 100644 --- a/website/docs/doc/GeneralUpdate.Extension.md +++ b/website/docs/doc/GeneralUpdate.Extension.md @@ -676,4 +676,4 @@ report-extension_1.0.0.zip - [扩展管理示例](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Hub/Samples/ExtensionSample.cs) - [GeneralUpdate 仓库](https://github.com/GeneralLibrary/GeneralUpdate) -- [打包指南](../guide/Packaging) +- [打包指南](../guide/Deployment and Operations) diff --git a/website/docs/guide/Packaging.md b/website/docs/guide/Deployment and Operations.md similarity index 56% rename from website/docs/guide/Packaging.md rename to website/docs/guide/Deployment and Operations.md index e8263bf..26a344a 100644 --- a/website/docs/guide/Packaging.md +++ b/website/docs/guide/Deployment and Operations.md @@ -1,10 +1,10 @@ --- -sidebar_position: 6 +sidebar_position: 1 --- -# 打包与部署 +# 部署与运维指南 -本文档介绍如何将应用程序与其更新系统打包,分发给最终用户。 +本文档涵盖应用程序打包部署、平台适配、故障排查和运维诊断。 --- @@ -120,7 +120,7 @@ await new GeneralUpdateBootstrap() **避免 C 盘权限问题:** - 建议默认安装到 `%LOCALAPPDATA%` 而非 `C:\Program Files\` -- 如必须安装在 C 盘,参考 [权限指南](./Permission) 配置注册表降权 +- 如必须安装在 C 盘,参考下方 [Windows 权限处理](#五windows-权限处理) 章节 **Windows 发布命令:** @@ -238,7 +238,167 @@ jobs: --- -## 五、版本号管理 +## 五、Windows 权限处理 + +### UAC 与安装目录 + +![](imgs\UAC.png) + +使用 GeneralUpdate 进行自动更新时,如果更新目录位于 C 盘,尤其在替换文件或应用补丁时可能会遇到权限问题。Windows 11 对 C 盘某些目录的权限管理比以往更加严格。 + +以下目录可能触发权限问题: + +| 名称 | 目录 | +| --- | --- | +| 系统文件夹 | C:\Windows | +| 注册表配置 | C:\Windows\System32\config | +| 驱动文件夹 | C:\Windows\System32\drivers | +| 程序文件夹 | C:\Program Files 和 C:\Program Files (x86) | + +推荐的避免权限问题的目录: + +| 名称 | 目录 | +| --- | --- | +| 用户数据目录 | AppData | +| 系统临时目录 | Temp | + +### 降低 UAC 级别 + +> **警告:** 以下方法不建议在生产环境中使用,可能对用户造成安全风险。 + +如果在更新过程中遇到 UAC 弹窗或权限拒绝问题,可考虑通过修改注册表降低 UAC 控制级别: + +| 注册表项 | 新值 | 默认值 | +| --- | --- | --- | +| enableLUA | 0 | 1 | +| ConsentPromptBehaviorAdmin | 0 | 5 | + +更新前修改以上注册表(重启电脑后生效),更新完成后务必恢复原值。 + +**C# 修改注册表:** + +```csharp +using Microsoft.Win32; + +public void UpdateRegistry() +{ + const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; + + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) + { + if (key != null) + { + key.SetValue("EnableLUA", 0, RegistryValueKind.DWord); + key.SetValue("ConsentPromptBehaviorAdmin", 0, RegistryValueKind.DWord); + } + } +} +``` + +**批处理脚本修改注册表:** + +```bat +@echo off +REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA /t REG_DWORD /d 0 /f +REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f +``` + +**参考链接:** +- [User Account Control 工作原理](https://learn.microsoft.com/zh-cn/windows/security/application-security/application-control/user-account-control/how-it-works) +- [Windows 用户账户控制](https://blog.walterlv.com/post/windows-user-account-control.html) + +--- + +## 六、文件占用排查 + +### Windows 平台 + +即使应用在自动升级前已关闭,在特殊情况下(如后台服务未退出)仍可能出现文件占用。此时可使用微软的 **handle.exe** 工具检查指定目录下是否有进程在运行。 + +`handle.exe` 是 Microsoft Sysinternals 提供的命令行工具,用于显示哪些进程打开了指定文件。在 C# 中可通过 `System.Diagnostics.Process` 调用。 + +```csharp +using System; +using System.Diagnostics; + +class Program +{ + static void Main() + { + Process process = new Process(); + process.StartInfo.FileName = "handle.exe"; + process.StartInfo.Arguments = "filename"; // 替换为实际的文件或目录路径 + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.Start(); + + string output = process.StandardOutput.ReadToEnd(); + Console.WriteLine(output); + + process.WaitForExit(); + } +} +``` + +**如果仍存在文件占用:** +1. 检查是否有后台服务未关闭 +2. 使用 `handle.exe` 排查占用进程 +3. 考虑使用强制终止或重启后更新策略 + +**参考链接:** +- [Handle - Sysinternals](https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle) + +--- + +## 七、崩溃转储诊断 + +在自动更新过程中,如果更新失败或更新后程序崩溃,可使用 **ProcDump** 工具导出 dump 文件进行分析。 + +ProcDump 是 Microsoft Sysinternals 的命令行实用工具,主要用于监控应用程序的 CPU 峰值并在峰值期间生成崩溃转储。管理员或开发人员可使用这些转储来确定崩溃原因。ProcDump 还支持挂起窗口监控、未处理异常监控,并可基于系统性能计数器值生成转储。 + +### C# 调用 ProcDump + +```csharp +using System; +using System.Diagnostics; + +public class Program +{ + public static void Main() + { + var procDumpPath = @"C:\Path\To\procdump.exe"; + var processId = 1234; // 需要 dump 的进程 ID + var dumpFilePath = @"C:\Path\To\dumpfile.dmp"; + + var startInfo = new ProcessStartInfo + { + FileName = procDumpPath, + Arguments = $"-ma {processId} {dumpFilePath}", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + var process = new Process { StartInfo = startInfo }; + process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data); + process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data); + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + process.WaitForExit(); + } +} +``` + +**参考链接:** +- [ProcDump - Sysinternals](https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump) + +--- + +## 八、版本号管理 ### 推荐策略 @@ -261,7 +421,7 @@ jobs: --- -## 六、检查清单 +## 九、部署检查清单 部署前确认: @@ -280,6 +440,5 @@ jobs: ## 相关资源 - **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — 补丁包和配置生成工具 -- **[权限指南](./Permission)** — Windows UAC 权限处理 -- **[入门实战手册](../quickstart/Beginner%20cookbook)** — 从零跑通更新闭环 +- **[入门实战手册](../quickstart/Beginner cookbook)** — 从零跑通更新闭环 - **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — 核心更新引擎架构 diff --git a/website/docs/guide/Dump.md b/website/docs/guide/Dump.md deleted file mode 100644 index 023adb4..0000000 --- a/website/docs/guide/Dump.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -sidebar_position: 4 ---- - -### Dump Files - -During the process of automatic updates, if an update fails or if the program crashes after the update, you can use the ProcDump tool to help export dump files. ProcDump is a command-line utility primarily used to monitor an application's CPU spikes and generate crash dumps during these spikes. Administrators or developers can use these dumps to determine the cause of the spikes. ProcDump also supports hung window monitoring (using the same definition as Windows and Task Manager), unhandled exception monitoring, and can generate dumps based on system performance counter values. It can also be used as a general-purpose process dump utility that can be embedded into other scripts. - -##### (1) Windows Platform - -C# Implementation for Calling ProcDump: - -```c# -using System; -using System.Diagnostics; - -public class Program -{ - public static void Main() - { - var procDumpPath = @"C:\Path\To\procdump.exe"; - var processId = 1234; // The ID of the process you want to dump - var dumpFilePath = @"C:\Path\To\dumpfile.dmp"; - - var startInfo = new ProcessStartInfo - { - FileName = procDumpPath, - Arguments = $"-ma {processId} {dumpFilePath}", - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true - }; - - var process = new Process { StartInfo = startInfo }; - process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data); - process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data); - - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - - process.WaitForExit(); - } -} -``` - -References: - -- https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump \ No newline at end of file diff --git a/website/docs/guide/FAQ.md b/website/docs/guide/FAQ.md deleted file mode 100644 index 3e60d12..0000000 --- a/website/docs/guide/FAQ.md +++ /dev/null @@ -1,338 +0,0 @@ ---- -sidebar_position: 8 ---- - -# 常见问题 (FAQ) - -## 基础概念 - -### Q1: GeneralUpdate 是什么? - -GeneralUpdate 是一个基于 .NET Standard 2.0 的跨平台自动更新框架。它提供了完整的应用程序更新解决方案,包括版本检查、下载管理、二进制差分更新、驱动更新、插件管理等功能。 - -### Q2: ClientCore 和 Core 有什么区别? - -| | ClientCore | Core | -|---|---|---| -| **运行位置** | 主程序进程内 | 独立升级进程 | -| **职责** | 检查更新、下载包、启动升级助手 | 解压、打补丁、替换文件、启动新版本 | -| **依赖方向** | 引用 Core 的共享类型 | 被 ClientCore 启动(通过 IPC) | -| **NuGet 包** | `GeneralUpdate.ClientCore` | `GeneralUpdate.Core` | - -**简单来说:** ClientCore "检查和下载",Core "安装和替换"。 - -### Q3: 什么是差分更新?为什么需要它? - -差分更新只下载两个版本之间的**变化部分**,而不是下载完整的安装包。 - -- **全量更新:** 下载 50MB → 解压 50MB → 覆盖安装 -- **差分更新:** 下载 5MB (补丁) → 解压 → BSDiff 算法合并 → 仅 5MB 下载 - -对于频繁更新的应用,差分更新可节省 80%-95% 的带宽。 - -### Q4: GeneralUpdate 支持哪些平台? - -| 操作系统 | 支持状态 | 备注 | -|----------|----------|------| -| Windows 10/11 | ✅ 完整支持 | 包括 WPF/WinForms/WinUI/Avalonia/Console | -| Linux (Ubuntu/Debian/Fedora) | ✅ 完整支持 | Avalonia/Console | -| macOS | ✅ 完整支持 | Avalonia/Console | -| Android | ✅ 通过 MAUI | 仅 OSS 模式 | -| 麒麟 V10 (飞腾/鲲鹏) | ✅ 已验证 | 国产化平台 | -| 统信 UOS | ✅ 已验证 | 国产化平台 | -| 龙芯 (LoongArch) | ✅ 已验证 | 国产化平台 | - ---- - -## 安装与配置 - -### Q5: 最简配置需要多少代码? - -使用 `ConfiginfoBuilder` 零配置模式: - -```csharp -using GeneralUpdate.ClientCore; -using GeneralUpdate.Common.Shared.Object; - -var config = ConfiginfoBuilder - .Create("https://your-server.com/api/update/check", - "your-token", "Bearer") - .Build(); - -await new GeneralClientBootstrap() - .SetConfig(config) - .LaunchAsync(); -``` - -仅需 3 个参数,其它从 `.csproj` 自动提取。 - -### Q6: 如何配置黑名单? - -```csharp -var config = new Configinfo -{ - // 跳过特定文件 - BlackFiles = new List { "appsettings.json", "userdata.db" }, - - // 跳过特定格式 - BlackFormats = new List { ".log", ".cache", ".tmp" }, - - // 跳过特定目录 - SkipDirectorys = new List { "logs", "temp", "userdata" } -}; -``` - -默认已跳过:`System.*.dll`、`.patch`、`.pdb`、`.rar`、`.tar`、`.json`、`.zip` 文件,以及 `app-`、`fail` 开头的目录。 - -### Q7: 静默更新如何配置? - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.EnableSilentUpdate, true) - .SetConfig(config) - .LaunchAsync(); -``` - -启用后: -- 每 20 分钟(可配置)后台轮询检查新版本 -- 发现新版本后静默下载 -- 主程序退出时自动触发升级 -- 无需用户交互 - ---- - -## 版本管理 - -### Q8: 版本号格式要求是什么? - -使用语义化版本(SemVer 2.0)格式:`Major.Minor.Patch.Build` - -- `1.0.0.0` ✓ -- `2.1.3.5` ✓ -- `1.0` ✗(不完整) -- `v1.0.0` ✗(含前缀) - -### Q9: 如何处理多版本跳级更新? - -GeneralUpdate 自动支持逐版本更新。如果客户端版本是 `1.0.0.0`,服务端有 `1.0.1.0`、`1.0.2.0`、`1.1.0.0` 三个版本: - -``` -客户端 1.0.0.0 - → 下载 patch_v1.0.1.zip → 更新到 1.0.1.0 - → 下载 patch_v1.0.2.zip → 更新到 1.0.2.0 - → 下载 patch_v1.1.0.zip → 更新到 1.1.0.0 -``` - -按发布日期逐个升级,确保每步都经过完整校验。 - -### Q10: 可以实现强制更新吗? - -可以。服务端在版本信息中设置 `IsForcibly: true`: - -```json -{ - "Version": "2.0.0.0", - "IsForcibly": true, - "UpdateLog": "重要安全更新,必须安装" -} -``` - -强制更新时,客户端的 `AddListenerUpdatePrecheck` 回调返回值会被忽略,更新一定执行。 - ---- - -## 下载与网络 - -### Q11: 支持断点续传吗? - -支持。下载中断后,下次启动会从断点继续下载。通过 `EnableResume` 选项控制(默认启用)。 - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.EnableResume, true) - .SetConfig(config) - .LaunchAsync(); -``` - -### Q12: 下载超时如何配置? - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.DownloadTimeOut, 120) // 120 秒超时 - .SetConfig(config) - .LaunchAsync(); -``` - -默认超时 30 秒。建议根据更新包大小和网络环境调整。 - -### Q13: 可以并发下载多个版本吗? - -可以。通过 `MaxConcurrency` 全局选项配置: - -```csharp -Option.MaxConcurrency.SetValue(5); // 最多同时下载 5 个版本 -``` - ---- - -## 差分更新 - -### Q14: 差分更新 vs 全量更新,如何选择? - -| 场景 | 建议模式 | -|------|----------| -| 日常小版本更新 | 差分更新(默认) | -| 大版本跨越(如 1.x → 2.x) | 全量更新 | -| 文件变化 < 20% | 差分更新 | -| 文件变化 > 80% | 全量更新 | -| 首次安装 | 全量更新 | - -```csharp -// 关闭差分更新 -await new GeneralClientBootstrap() - .Option(UpdateOption.Patch, false) - .SetConfig(config) - .LaunchAsync(); -``` - -### Q15: 补丁包是如何生成的? - -使用 [GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) 的「补丁包」功能: - -1. 选择旧版本目录(如 `MyApp_v1.0.0`) -2. 选择新版本目录(如 `MyApp_v1.0.1`) -3. 设置输出目录 -4. 点击「构建」 - -工具自动: -- 对比两个目录的文件差异 -- 为修改的文件生成 BSDiff 补丁(`.patch`) -- 收集新增文件 -- 记录需要删除的文件(`delete_files.json`) -- 打包为 `.zip` - ---- - -## 文件与权限 - -### Q16: 更新时遇到文件被占用怎么办? - -更新过程由独立的升级助手进程(Core)执行,主程序已退出,通常不会有文件占用问题。 - -如果仍有占用: -1. 检查是否有后台服务未关闭 -2. 使用 [文件占用指南](./File occupancy) 中的 `handle.exe` 排查 -3. 考虑使用强制重启后更新策略 - -### Q17: Linux/macOS 上文件权限怎么处理? - -使用 `UnixPermissionHooks` 或 `CustomPermissionHooks`: - -```csharp -// 自动 chmod +x -await new GeneralClientBootstrap() - .Hooks() - .SetConfig(config) - .LaunchAsync(); -``` - -或通过 `Configinfo.Script` 指定自定义脚本: - -```csharp -var config = new Configinfo -{ - Script = "/path/to/permission-script.sh", - // ... -}; -``` - ---- - -## 故障排查 - -### Q18: 更新失败如何诊断? - -1. **检查事件监听:** 确保注册了所有异常和错误监听器 -2. **查看 Bowl 日志:** 如果启用了 Bowl,检查 `fail/` 目录下的 Dump 和诊断文件 -3. **检查服务端日志:** 确认版本信息正确返回 -4. **检查网络:** 确认客户端可以访问服务端 API 和下载地址 -5. **检查版本号:** 确保客户端和服务端的版本号格式一致 - -### Q19: 如何实现回滚? - -GeneralUpdate 有自动备份和回滚机制: - -```csharp -// 确保启用备份 -await new GeneralClientBootstrap() - .Option(UpdateOption.BackUp, true) - .SetConfig(config) - .LaunchAsync(); -``` - -更新失败或 Bowl 检测到崩溃时,自动从备份目录恢复文件。 - -### Q20: 如何在开发环境测试更新流程? - -使用 [GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) 的「模拟更新」功能: - -1. 选择应用程序目录和补丁包 -2. 设置版本号和平台 -3. 点击「开始模拟」 - -工具自动: -- 启动本地模拟服务端 -- 发布并运行 ClientSample 和 UpgradeSample -- 执行完整更新流程 -- 生成测试报告 - ---- - -## 服务端 - -### Q21: 服务端 API 需要自己实现吗? - -示例项目中提供了简单的服务端示例。生产环境需要自行实现或使用商业版本 [GeneralSpacestation](https://www.justerzhu.cn/)。 - -**需要实现的 API:** -1. `POST /Upgrade/Verification` — 版本验证 -2. `POST /Upgrade/Report` — 状态上报 -3. `GET /patch/{filename}` — 补丁包下载 - -### Q22: 可以和 CI/CD 集成吗? - -可以。推荐集成方式: - -1. **CI 构建:** 编译新旧版本 -2. **Tools 命令行:** 使用 GeneralUpdate.Tools 生成补丁包(CLI 模式) -3. **上传:** 将补丁包和 `version.json` 上传到服务器/OSS -4. **更新清单:** 更新服务端版本数据库 - ---- - -## OSS 模式 - -### Q23: OSS 模式和标准模式有什么区别? - -| | 标准模式 | OSS 模式 | -|---|---|---| -| **服务端** | 需要 HTTP API 服务 | 仅需对象存储(S3/OSS/MinIO) | -| **版本检查** | API 调用 | 读取 `version.json` 文件 | -| **适用场景** | 有后端服务的应用 | 客户端工具、桌面软件 | -| **成本** | 需要维护服务 | 仅存储和流量费用 | - -### Q24: 如何从标准模式迁移到 OSS 模式? - -1. 生成 `version.json`(使用 GeneralUpdate.Tools OSS 配置模块) -2. 将 `version.json` 和补丁包上传到对象存储 -3. 客户端修改 `AppType` 为 `OssClient` -4. 配置 OSS 地址 - ---- - -## 相关资源 - -- **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — 核心更新引擎 -- **[入门实战手册](../quickstart/Beginner%20cookbook)** — 从零跑通更新闭环 -- **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — 打包工具 -- **[GeneralUpdate.Bowl](../doc/GeneralUpdate.Bowl)** — 崩溃监控与回滚 diff --git a/website/docs/guide/File occupancy.md b/website/docs/guide/File occupancy.md deleted file mode 100644 index 0686e0f..0000000 --- a/website/docs/guide/File occupancy.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -sidebar_position: 2 ---- - -### File Occupancy - -#### (1) Windows Platform - -Even though applications are closed during automatic upgrades, file occupancy can occur if processes are still running due to special circumstances. In such cases, you can use Microsoft's handle.exe tool to check if there are any processes running in a specified directory. "handle.exe" is a command-line tool provided by Microsoft that displays which processes have opened specific files. In C#, you can invoke handle.exe using the `System.Diagnostics.Process` class. If a process is detected, it will return a list of processes running in that directory. - -```c# -using System; -using System.Diagnostics; - -class Program -{ - static void Main() - { - Process process = new Process(); - process.StartInfo.FileName = "handle.exe"; - process.StartInfo.Arguments = "filename"; // Replace 'filename' with the actual file or directory - process.StartInfo.UseShellExecute = false; - process.StartInfo.RedirectStandardOutput = true; - process.Start(); - - string output = process.StandardOutput.ReadToEnd(); - Console.WriteLine(output); - - process.WaitForExit(); - } -} -``` - -References: -- https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle diff --git a/website/docs/guide/Permission.md b/website/docs/guide/Permission.md deleted file mode 100644 index 9398fc3..0000000 --- a/website/docs/guide/Permission.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 1 ---- - -### Permissions - -#### (1) Windows Platform - -![](imgs\UAC.png) - -When using GeneralUpdate for automatic updates, you may encounter permission issues if the update directory is on the C drive, especially when replacing files or applying patches. With the introduction of Windows 11, permission management for certain directories on the C drive has become more stringent compared to previous Windows operating systems. - -It's important to be aware of which directories might trigger permission issues: - -| Name | Directory | -| --------------- | ------------------------------------------- | -| System Folder | C:\Windows | -| Registry Config | C:\Windows\System32\config | -| Driver Folder | C:\Windows\System32\drivers | -| Program Folder | C:\Program Files and C:\Program Files (x86) | - -Recommended directories to avoid permission issues: - -| Name | Directory | -| -------------------------- | --------- | -| User Data Directory | AppData | -| System Temporary Directory | Temp | - -### Lowering UAC - -The following method is not recommended for use in production environments as it may cause issues for users. If you encounter UAC (User Account Control) prompts or permission/access denied issues during updates, you might consider lowering the UAC control level. This can be done by modifying the registry as follows: - -| Registry Name | New Value | Default Value | -| -------------------------- | --------- | ------------- | -| enableLUA | 0 | 1 | -| ConsentPromptBehaviorAdmin | 0 | 5 | - -Modify the above registry settings before the update (effective after restarting the computer), and be sure to restore them after the update is complete. - -C# code to modify the registry: - -```c# -using Microsoft.Win32; - -public void UpdateRegistry() -{ - const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; - - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) - { - if (key != null) - { - key.SetValue("EnableLUA", 0, RegistryValueKind.DWord); - key.SetValue("ConsentPromptBehaviorAdmin", 0, RegistryValueKind.DWord); - } - } -} -``` - -Batch script to modify the registry: - -```bat -@echo off -REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA /t REG_DWORD /d 0 /f -REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f -``` - -References: -- https://learn.microsoft.com/zh-cn/windows/security/application-security/application-control/user-account-control/how-it-works -- https://blog.walterlv.com/post/windows-user-account-control.html \ No newline at end of file diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md b/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md index ac9e4a3..3e6b3ad 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md @@ -362,4 +362,4 @@ MyApp/ - [Bowl Sample Code](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Bowl) - [GeneralUpdate Repository](https://github.com/GeneralLibrary/GeneralUpdate) -- [Dump Guide](../guide/Dump) +- [Dump Guide](../guide/Deployment and Operations) diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Differential.md b/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Differential.md index c423390..8f55e27 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Differential.md +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Differential.md @@ -288,4 +288,4 @@ await new GeneralUpdateBootstrap() - [GeneralUpdate Repository](https://github.com/GeneralLibrary/GeneralUpdate) - [Differential Sample](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Hub/Samples/DifferentialSample.cs) - [Core DiffPipeline Docs](GeneralUpdate.Core) -- [Packaging Guide](../guide/Packaging) +- [Packaging Guide](../guide/Deployment and Operations) diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md b/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md index e8f87d6..651b3ff 100644 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md @@ -518,4 +518,4 @@ Per-extension setting > Global setting > Default (false) - [Extension Management Sample](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Hub/Samples/ExtensionSample.cs) - [GeneralUpdate Repository](https://github.com/GeneralLibrary/GeneralUpdate) -- [Packaging Guide](../guide/Packaging) +- [Packaging Guide](../guide/Deployment and Operations) diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Deployment and Operations.md b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Deployment and Operations.md new file mode 100644 index 0000000..2ac05b3 --- /dev/null +++ b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Deployment and Operations.md @@ -0,0 +1,444 @@ +--- +sidebar_position: 1 +--- + +# Deployment & Operations Guide + +This document covers application packaging & deployment, platform adaptation, troubleshooting, and operational diagnostics. + +--- + +## 1. Patch Generation + +### Using GeneralUpdate.Tools (Recommended) + +[GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) is the recommended patch generation tool with a visual interface and full verification capabilities. + +**Steps:** + +1. Download and launch GeneralUpdate.Tools +2. Switch to the "Patch Package" tab +3. Select the old version directory (source path) +4. Select the new version directory (target path) +5. Set the patch output path +6. Fill in the package name and version number +7. Click "Build" + +See [GeneralUpdate.Tools Documentation](../quickstart/GeneralUpdate.PacketTool) for details. + +### Programmatic Generation with Differential API + +```csharp +using GeneralUpdate.Differential; + +// Generate incremental patch +var sourcePath = @"C:\Builds\MyApp_v1.0.0"; +var targetPath = @"C:\Builds\MyApp_v1.0.1"; +var patchPath = @"C:\Builds\patches\v1.0.1"; + +await DifferentialCore.Instance.Clean(sourcePath, targetPath, patchPath); + +// Package the patchPath directory as .zip and upload to server +``` + +--- + +## 2. Client Packaging + +### Directory Structure + +Recommended client installation directory structure: + +``` +MyApp/ +├── MyApp.exe ← Main executable +├── MyApp.Core.dll ← Core library +├── UpgradeSample.exe ← Upgrade helper (alongside main app) +├── GeneralUpdate.Core.dll ← Upgrade helper dependency +├── GeneralUpdate.ClientCore.dll ← Client update component +├── GeneralUpdate.Differential.dll +├── generalupdate.manifest.json ← Auto-generated manifest +├── appsettings.json ← App config (add to blacklist) +└── resources/ + └── ... +``` + +### Client References + +```xml + + +``` + +```xml + + +``` + +### Upgrade Helper — Independent Project + +The upgrade helper (Upgrade) must be a **standalone executable project**, compiled separately from the main application: + +``` +MySolution/ +├── src/ +│ ├── MyApp/ ← Main app project +│ │ ├── MyApp.csproj +│ │ └── Program.cs +│ └── MyApp.Upgrade/ ← Upgrade helper project +│ ├── MyApp.Upgrade.csproj +│ └── Program.cs +└── MySolution.sln +``` + +**Minimal Upgrade Helper Program.cs:** + +```csharp +using GeneralUpdate.Core; + +await new GeneralUpdateBootstrap() + .AddListenerException((_, args) => + { + Console.WriteLine($"Upgrade error: {args.Exception.Message}"); + }) + .LaunchAsync(); +``` + +--- + +## 3. Platform-Specific Packaging + +### Windows + +**Create installer with NSIS:** + +- [NSIS Official Site](https://nsis.sourceforge.io/Download) +- NSIS script handles: creating install directory, copying files, registering shortcuts +- Place main app and upgrade helper in the same directory +- Ensure the install directory has write permission for the current user + +**Avoid C: drive permission issues:** + +- Default install path: `%LOCALAPPDATA%` rather than `C:\Program Files\` +- If C: drive is required, see the [Windows Permission Handling](#5-windows-permission-handling) section below + +**Windows publish commands:** + +```bash +dotnet publish src/MyApp/MyApp.csproj -c Release -r win-x64 --self-contained +dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r win-x64 --self-contained +``` + +### Linux + +**.deb packages (Debian/Ubuntu):** + +See [Avalonia Deployment Docs](https://docs.avaloniaui.net/docs/deployment/debian-ubuntu) + +**AppImage:** + +Universal portable packaging format for Linux, runs without installation. + +**Linux permission handling:** + +```csharp +// Use UnixPermissionHooks in the upgrade helper +await new GeneralUpdateBootstrap() + .Hooks() + .LaunchAsync(); +``` + +Or use a custom script: + +```csharp +var config = new Configinfo +{ + Script = "/bin/bash chmod -R +x $InstallPath", + // ... +}; +``` + +**Linux publish commands:** + +```bash +dotnet publish src/MyApp/MyApp.csproj -c Release -r linux-x64 --self-contained +dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r linux-x64 --self-contained +``` + +### macOS + +**.app Bundle:** + +macOS apps are typically packaged as `.app` directory structures. Ensure the upgrade helper is in the main app's `Contents/MacOS/` directory. + +**Code Signing:** + +macOS requires code signing for apps to run properly (especially on Apple Silicon): + +```bash +codesign --deep --force --verify --verbose --sign "Developer ID" MyApp.app +``` + +**Notarization:** + +Submit to Apple notarization before distributing: + +```bash +xcrun notarytool submit MyApp.dmg --apple-id your@email.com --wait +``` + +**macOS publish commands:** + +```bash +dotnet publish src/MyApp/MyApp.csproj -c Release -r osx-x64 --self-contained +dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r osx-x64 --self-contained +``` + +--- + +## 4. CI/CD Integration + +### GitHub Actions Example + +```yaml +name: Build and Package + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: Publish Client + run: dotnet publish src/MyApp/MyApp.csproj -c Release -r win-x64 -o publish/MyApp + + - name: Publish Upgrade + run: dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r win-x64 -o publish/MyApp + + - name: Generate Patch + run: | + # Use GeneralUpdate.Tools CLI or other scripts to generate patches + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: release-package + path: publish/ +``` + +--- + +## 5. Windows Permission Handling + +### UAC and Installation Directories + +![](imgs\UAC.png) + +When using GeneralUpdate for automatic updates, permission issues may occur if the update directory is on the C: drive, especially when replacing files or applying patches. Windows 11 has stricter permission management for certain C: drive directories. + +Directories that may trigger permission issues: + +| Name | Directory | +| --- | --- | +| System Folder | C:\Windows | +| Registry Config | C:\Windows\System32\config | +| Driver Folder | C:\Windows\System32\drivers | +| Program Folder | C:\Program Files and C:\Program Files (x86) | + +Recommended directories to avoid permission issues: + +| Name | Directory | +| --- | --- | +| User Data Directory | AppData | +| System Temporary Directory | Temp | + +### Lowering UAC Level + +> **Warning:** The following method is not recommended for production use as it may pose security risks. + +If you encounter UAC prompts or permission denied issues during updates, you may lower the UAC control level by modifying the registry: + +| Registry Key | New Value | Default Value | +| --- | --- | --- | +| enableLUA | 0 | 1 | +| ConsentPromptBehaviorAdmin | 0 | 5 | + +Modify the above registry settings before the update (effective after restart), and restore them after the update completes. + +**C# registry modification:** + +```csharp +using Microsoft.Win32; + +public void UpdateRegistry() +{ + const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; + + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) + { + if (key != null) + { + key.SetValue("EnableLUA", 0, RegistryValueKind.DWord); + key.SetValue("ConsentPromptBehaviorAdmin", 0, RegistryValueKind.DWord); + } + } +} +``` + +**Batch script:** + +```bat +@echo off +REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA /t REG_DWORD /d 0 /f +REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f +``` + +**References:** +- [How User Account Control Works](https://learn.microsoft.com/en-us/windows/security/application-security/application-control/user-account-control/how-it-works) +- [Windows UAC Blog](https://blog.walterlv.com/post/windows-user-account-control.html) + +--- + +## 6. File Occupancy Troubleshooting + +### Windows Platform + +Even when applications are closed before automatic upgrades, file occupancy can occur if background processes are still running. Use Microsoft's **handle.exe** tool to check for running processes in a specified directory. + +`handle.exe` is a command-line tool from Microsoft Sysinternals that shows which processes have opened specific files. It can be invoked from C# via `System.Diagnostics.Process`. + +```csharp +using System; +using System.Diagnostics; + +class Program +{ + static void Main() + { + Process process = new Process(); + process.StartInfo.FileName = "handle.exe"; + process.StartInfo.Arguments = "filename"; // Replace with actual file or directory path + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.Start(); + + string output = process.StandardOutput.ReadToEnd(); + Console.WriteLine(output); + + process.WaitForExit(); + } +} +``` + +**If file occupancy persists:** +1. Check for background services that haven't been shut down +2. Use `handle.exe` to identify the occupying process +3. Consider forced termination or post-reboot update strategies + +**Reference:** +- [Handle - Sysinternals](https://learn.microsoft.com/en-us/sysinternals/downloads/handle) + +--- + +## 7. Crash Dump Diagnostics + +During automatic updates, if an update fails or the program crashes after updating, use the **ProcDump** tool to export dump files for analysis. + +ProcDump is a command-line utility from Microsoft Sysinternals primarily used for monitoring CPU spikes in applications and generating crash dumps during those spikes. Administrators or developers can use these dumps to identify the cause of crashes. ProcDump also supports hung window monitoring, unhandled exception monitoring, and can generate dumps based on system performance counter values. + +### C# Invocation of ProcDump + +```csharp +using System; +using System.Diagnostics; + +public class Program +{ + public static void Main() + { + var procDumpPath = @"C:\Path\To\procdump.exe"; + var processId = 1234; // The ID of the process to dump + var dumpFilePath = @"C:\Path\To\dumpfile.dmp"; + + var startInfo = new ProcessStartInfo + { + FileName = procDumpPath, + Arguments = $"-ma {processId} {dumpFilePath}", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + var process = new Process { StartInfo = startInfo }; + process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data); + process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data); + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + process.WaitForExit(); + } +} +``` + +**Reference:** +- [ProcDump - Sysinternals](https://learn.microsoft.com/en-us/sysinternals/downloads/procdump) + +--- + +## 8. Version Number Management + +### Recommended Strategies + +| Strategy | Description | Use Case | +|----------|-------------|----------| +| **Manual** | Hardcode `` in `.csproj` | Small projects | +| **Git Tag** | Read version from Git tags | Projects with CI/CD | +| **MinVer** | Auto-calculate version from Git history | Recommended | +| **Nerdbank.GitVersioning** | Precise Git version management | Large projects | + +### MinVer Configuration Example + +```xml + + + all + runtime; build; native; contentfiles; analyzers + +``` + +--- + +## 9. Deployment Checklist + +Before deploying, confirm: + +- [ ] Main app references `GeneralUpdate.ClientCore` +- [ ] Upgrade helper is a standalone executable project referencing `GeneralUpdate.Core` +- [ ] Upgrade helper deployed in the same directory as the main app +- [ ] `generalupdate.manifest.json` can be auto-generated via Tools "Config Generator" +- [ ] Full update flow verified in test environment using Tools "Simulate Update" +- [ ] Blacklist correctly configured (protect user data from overwrite) +- [ ] Platform-specific permissions configured (Linux `chmod`, Windows registry) +- [ ] Version numbers follow SemVer format +- [ ] Server API deployed and configured with correct version info + +--- + +## Related Resources + +- **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — Patch and config generation tool +- **[Beginner Cookbook](../quickstart/Beginner cookbook)** — Complete end-to-end update walkthrough +- **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — Core update engine architecture diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Dump.md b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Dump.md deleted file mode 100644 index 023adb4..0000000 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Dump.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -sidebar_position: 4 ---- - -### Dump Files - -During the process of automatic updates, if an update fails or if the program crashes after the update, you can use the ProcDump tool to help export dump files. ProcDump is a command-line utility primarily used to monitor an application's CPU spikes and generate crash dumps during these spikes. Administrators or developers can use these dumps to determine the cause of the spikes. ProcDump also supports hung window monitoring (using the same definition as Windows and Task Manager), unhandled exception monitoring, and can generate dumps based on system performance counter values. It can also be used as a general-purpose process dump utility that can be embedded into other scripts. - -##### (1) Windows Platform - -C# Implementation for Calling ProcDump: - -```c# -using System; -using System.Diagnostics; - -public class Program -{ - public static void Main() - { - var procDumpPath = @"C:\Path\To\procdump.exe"; - var processId = 1234; // The ID of the process you want to dump - var dumpFilePath = @"C:\Path\To\dumpfile.dmp"; - - var startInfo = new ProcessStartInfo - { - FileName = procDumpPath, - Arguments = $"-ma {processId} {dumpFilePath}", - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true - }; - - var process = new Process { StartInfo = startInfo }; - process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data); - process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data); - - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - - process.WaitForExit(); - } -} -``` - -References: - -- https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump \ No newline at end of file diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/FAQ.md b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/FAQ.md deleted file mode 100644 index b4b015a..0000000 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/FAQ.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -sidebar_position: 8 ---- - -# Frequently Asked Questions - -## Basic Concepts - -### Q1: What is GeneralUpdate? - -GeneralUpdate is a cross-platform .NET Standard 2.0 automatic update framework. It provides a complete application update solution including version checking, download management, binary differential updates, driver updates, and plugin management. - -### Q2: What's the difference between ClientCore and Core? - -| | ClientCore | Core | -|---|---|---| -| **Runs in** | Main app process | Separate upgrade process | -| **Responsibility** | Check versions, download packages, launch upgrade | Decompress, apply patches, replace files, start new version | -| **Depends on** | References Core's shared types | Launched by ClientCore (via IPC) | -| **NuGet** | `GeneralUpdate.ClientCore` | `GeneralUpdate.Core` | - -**Simply put:** ClientCore "checks and downloads", Core "installs and replaces". - -### Q3: What is differential updating? - -Differential updating downloads only the **changes** between two versions instead of the full package. - -- **Full update:** Download 50MB → Decompress 50MB → Overwrite -- **Differential update:** Download 5MB (patch) → Decompress → BSDiff merge → Only 5MB downloaded - -For frequently updated apps, differential updates save 80%-95% bandwidth. - -### Q4: Which platforms are supported? - -| OS | Status | Notes | -|----|--------|-------| -| Windows 10/11 | ✅ Full support | WPF/WinForms/WinUI/Avalonia/Console | -| Linux (Ubuntu/Debian/Fedora) | ✅ Full support | Avalonia/Console | -| macOS | ✅ Full support | Avalonia/Console | -| Android | ✅ Via MAUI | OSS mode only | -| Kylin V10 (Phytium/Kunpeng) | ✅ Verified | Domestic platforms | -| UOS | ✅ Verified | Domestic platforms | -| Loongson (LoongArch) | ✅ Verified | Domestic platforms | - ---- - -## Installation & Configuration - -### Q5: What's the minimum code needed? - -Using the `ConfiginfoBuilder` zero-config mode: - -```csharp -using GeneralUpdate.ClientCore; -using GeneralUpdate.Common.Shared.Object; - -var config = ConfiginfoBuilder - .Create("https://your-server.com/api/update/check", - "your-token", "Bearer") - .Build(); - -await new GeneralClientBootstrap() - .SetConfig(config) - .LaunchAsync(); -``` - -Only 3 parameters needed — the rest auto-extracted from `.csproj`. - -### Q6: How to configure the blacklist? - -```csharp -var config = new Configinfo -{ - BlackFiles = new List { "appsettings.json", "userdata.db" }, - BlackFormats = new List { ".log", ".cache", ".tmp" }, - SkipDirectorys = new List { "logs", "temp", "userdata" } -}; -``` - -Defaults already skip: `System.*.dll`, `.patch`, `.pdb`, `.rar`, `.tar`, `.json`, `.zip` files, and `app-`, `fail` directories. - -### Q7: How to enable silent updates? - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.EnableSilentUpdate, true) - .SetConfig(config) - .LaunchAsync(); -``` - -When enabled: -- Background polling every 20 minutes (configurable) -- Silent download when new version found -- Auto-triggers upgrade when main app exits -- No user interaction required - ---- - -## Version Management - -### Q8: What version format is required? - -Semantic Versioning 2.0: `Major.Minor.Patch.Build` - -- `1.0.0.0` ✓ -- `2.1.3.5` ✓ -- `1.0` ✗ (incomplete) -- `v1.0.0` ✗ (contains prefix) - -### Q9: How are multi-version skip updates handled? - -GeneralUpdate automatically handles sequential version updates. If client is `1.0.0.0` and server has `1.0.1.0`, `1.0.2.0`, `1.1.0.0`: - -``` -Client 1.0.0.0 - → Download patch_v1.0.1.zip → Update to 1.0.1.0 - → Download patch_v1.0.2.zip → Update to 1.0.2.0 - → Download patch_v1.1.0.zip → Update to 1.1.0.0 -``` - -Each step uses complete verification before proceeding. - -### Q10: How to force an update? - -Set `IsForcibly: true` in the server response: - -```json -{ - "Version": "2.0.0.0", - "IsForcibly": true, - "UpdateLog": "Critical security update, must install" -} -``` - -When forced, the `AddListenerUpdatePrecheck` callback return value is ignored. - ---- - -## Download & Network - -### Q11: Is download resume supported? - -Yes. Downloads resume from the breakpoint on next startup. Controlled by `EnableResume` option (enabled by default). - -### Q12: How to configure download timeout? - -```csharp -.Option(UpdateOption.DownloadTimeOut, 120) // 120 seconds -``` - -Default is 30 seconds. Adjust based on package size and network conditions. - -### Q13: Can I download multiple versions concurrently? - -Yes. Configure via `MaxConcurrency`: - -```csharp -Option.MaxConcurrency.SetValue(5); // Max 5 concurrent downloads -``` - ---- - -## Differential Updates - -### Q14: Differential vs full update — when to use which? - -| Scenario | Recommended Mode | -|----------|-----------------| -| Regular minor updates | Differential (default) | -| Major version jumps (1.x → 2.x) | Full update | -| < 20% files changed | Differential | -| > 80% files changed | Full update | -| First install | Full update | - -### Q15: How are patches generated? - -Use [GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) Patch Package tab: - -1. Select old version directory -2. Select new version directory -3. Choose output directory -4. Click "Build" - -The tool automatically generates BSDiff patches for changed files and packages them as `.zip`. - ---- - -## Files & Permissions - -### Q16: What if files are locked during update? - -The upgrade process runs as a separate process (Core) after the main app exits, so file locks are rarely an issue. If still locked, check for background services and use `handle.exe` (Windows) to diagnose. - -### Q17: How to handle Linux/macOS permissions? - -```csharp -// Automatic chmod +x -await new GeneralClientBootstrap() - .Hooks() - .SetConfig(config) - .LaunchAsync(); -``` - -Or via custom script: - -```csharp -var config = new Configinfo -{ - Script = "/path/to/permission-script.sh" -}; -``` - ---- - -## Troubleshooting - -### Q18: How to diagnose update failures? - -1. **Check event listeners** — Register all exception and error listeners -2. **Check Bowl logs** — If Bowl enabled, inspect `fail/` directory -3. **Check server logs** — Confirm version info is returned correctly -4. **Check network** — Verify client can reach server API and download URLs -5. **Check versions** — Ensure consistent version format on both sides - -### Q19: How does rollback work? - -GeneralUpdate has automatic backup and rollback: - -```csharp -.Option(UpdateOption.BackUp, true) // Enable backup -``` - -On update failure or Bowl crash detection, files are automatically restored from backup. - -### Q20: How to test the update flow in development? - -Use [GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) "Simulate Update" feature: - -1. Select app directory and patch file -2. Set version numbers and platform -3. Click "Start Simulation" - -The tool auto-launches a local mock server, publishes test apps, and runs the complete update flow. - ---- - -## Server - -### Q21: Do I need to implement the server API myself? - -Sample projects provide a simple server example. For production, implement your own or use the commercial [GeneralSpacestation](https://www.justerzhu.cn/). - -**Required APIs:** -1. `POST /Upgrade/Verification` — Version verification -2. `POST /Upgrade/Report` — Status reporting -3. `GET /patch/{filename}` — Patch download - ---- - -## OSS Mode - -### Q22: What's the difference between OSS and standard mode? - -| | Standard Mode | OSS Mode | -|---|---|---| -| **Server** | HTTP API service required | Object storage only (S3/OSS/MinIO) | -| **Version check** | API call | Read `version.json` | -| **Use case** | Apps with backend services | Desktop tools, standalone apps | -| **Cost** | Server maintenance | Storage and bandwidth only | - -### Q23: How to migrate from standard to OSS mode? - -1. Generate `version.json` (use Tools OSS Config module) -2. Upload `version.json` and patches to object storage -3. Change client `AppType` to `OssClient` -4. Configure OSS URL - ---- - -## Related Resources - -- **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — Core update engine -- **[Beginner Cookbook](../quickstart/Beginner%20cookbook)** — Run through the full update loop -- **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — Packaging tools -- **[GeneralUpdate.Bowl](../doc/GeneralUpdate.Bowl)** — Crash monitoring & rollback diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/File occupancy.md b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/File occupancy.md deleted file mode 100644 index 0686e0f..0000000 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/File occupancy.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -sidebar_position: 2 ---- - -### File Occupancy - -#### (1) Windows Platform - -Even though applications are closed during automatic upgrades, file occupancy can occur if processes are still running due to special circumstances. In such cases, you can use Microsoft's handle.exe tool to check if there are any processes running in a specified directory. "handle.exe" is a command-line tool provided by Microsoft that displays which processes have opened specific files. In C#, you can invoke handle.exe using the `System.Diagnostics.Process` class. If a process is detected, it will return a list of processes running in that directory. - -```c# -using System; -using System.Diagnostics; - -class Program -{ - static void Main() - { - Process process = new Process(); - process.StartInfo.FileName = "handle.exe"; - process.StartInfo.Arguments = "filename"; // Replace 'filename' with the actual file or directory - process.StartInfo.UseShellExecute = false; - process.StartInfo.RedirectStandardOutput = true; - process.Start(); - - string output = process.StandardOutput.ReadToEnd(); - Console.WriteLine(output); - - process.WaitForExit(); - } -} -``` - -References: -- https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Packaging.md b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Packaging.md deleted file mode 100644 index 561a1c6..0000000 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Packaging.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -sidebar_position: 6 ---- - -# Packaging & Deployment - -This guide covers how to package your application with its update system for distribution to end users. - ---- - -## 1. Patch Generation - -### Using GeneralUpdate.Tools (Recommended) - -[GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) is the recommended patch generation tool with a visual interface and comprehensive validation. - -**Steps:** -1. Download and launch GeneralUpdate.Tools -2. Switch to the "Patch Package" tab -3. Select old version directory (source path) -4. Select new version directory (target path) -5. Set patch output path -6. Enter package name and version -7. Click "Build" - -See the [GeneralUpdate.Tools documentation](../quickstart/GeneralUpdate.PacketTool) for details. - -### Using the Differential API Programmatically - -```csharp -using GeneralUpdate.Differential; - -var sourcePath = @"C:\Builds\MyApp_v1.0.0"; -var targetPath = @"C:\Builds\MyApp_v1.0.1"; -var patchPath = @"C:\Builds\patches\v1.0.1"; - -await DifferentialCore.Instance.Clean(sourcePath, targetPath, patchPath); -// Package patchPath as .zip and upload to server -``` - ---- - -## 2. Client Packaging - -### Directory Structure - -Recommended installation directory layout: - -``` -MyApp/ -├── MyApp.exe ← Main application -├── MyApp.Core.dll ← Core libraries -├── UpgradeSample.exe ← Upgrade assistant (same directory) -├── GeneralUpdate.Core.dll ← Upgrade dependencies -├── GeneralUpdate.ClientCore.dll ← Client update component -├── GeneralUpdate.Differential.dll -├── generalupdate.manifest.json ← Auto-generated manifest -├── appsettings.json ← App config (add to blacklist) -└── resources/ -``` - -### Client References - -```xml - - -``` - -```xml - - -``` - -### Separate Upgrade Project - -The Upgrade assistant must be a **separate executable project**: - -``` -MySolution/ -├── src/ -│ ├── MyApp/ ← Main app project -│ │ ├── MyApp.csproj -│ │ └── Program.cs -│ └── MyApp.Upgrade/ ← Upgrade project -│ ├── MyApp.Upgrade.csproj -│ └── Program.cs -└── MySolution.sln -``` - -**Minimal Upgrade Program.cs:** - -```csharp -using GeneralUpdate.Core; - -await new GeneralUpdateBootstrap() - .AddListenerException((_, args) => - { - Console.WriteLine($"Upgrade error: {args.Exception.Message}"); - }) - .LaunchAsync(); -``` - ---- - -## 3. Platform-Specific Packaging - -### Windows - -**Using NSIS:** -- [NSIS Download](https://nsis.sourceforge.io/Download) -- Place main app and upgrade assistant in the same directory -- Default install to `%LOCALAPPDATA%` to avoid C drive permission issues -- For C drive installs, see [Permission Guide](./Permission) - -```bash -dotnet publish src/MyApp/MyApp.csproj -c Release -r win-x64 --self-contained -dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r win-x64 --self-contained -``` - -### Linux - -**Using .deb (Debian/Ubuntu):** See [Avalonia deployment docs](https://docs.avaloniaui.net/docs/deployment/debian-ubuntu) - -**Permission handling:** - -```csharp -await new GeneralUpdateBootstrap() - .Hooks() - .LaunchAsync(); -``` - -```bash -dotnet publish src/MyApp/MyApp.csproj -c Release -r linux-x64 --self-contained -dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r linux-x64 --self-contained -``` - -### macOS - -**Code signing:** -```bash -codesign --deep --force --verify --verbose --sign "Developer ID" MyApp.app -``` - -**Notarization:** -```bash -xcrun notarytool submit MyApp.dmg --apple-id your@email.com --wait -``` - -```bash -dotnet publish src/MyApp/MyApp.csproj -c Release -r osx-x64 --self-contained -dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r osx-x64 --self-contained -``` - ---- - -## 4. CI/CD Integration - -### GitHub Actions Example - -```yaml -name: Build and Package -on: - push: - tags: ['v*'] -jobs: - build: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '10.0.x' - - name: Publish Client - run: dotnet publish src/MyApp/MyApp.csproj -c Release -r win-x64 -o publish/MyApp - - name: Publish Upgrade - run: dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r win-x64 -o publish/MyApp - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: release-package - path: publish/ -``` - ---- - -## 5. Version Management - -### Recommended Strategies - -| Strategy | Description | Best For | -|----------|-------------|----------| -| **Manual** | Hardcode `` in `.csproj` | Small projects | -| **Git Tag** | Read version from Git tags | CI/CD pipelines | -| **MinVer** | Auto-calculate version from Git history | Recommended | -| **Nerdbank.GitVersioning** | Precise Git-based version management | Large projects | - ---- - -## 6. Deployment Checklist - -Before deploying, verify: - -- [ ] Main app references `GeneralUpdate.ClientCore` -- [ ] Upgrade assistant is a separate executable project referencing `GeneralUpdate.Core` -- [ ] Upgrade assistant deployed in the same directory as the main app -- [ ] `generalupdate.manifest.json` generated via Tools' Config Generator -- [ ] Full update flow tested via Tools' Simulate Update -- [ ] Blacklist configured correctly (protect user data from overwrites) -- [ ] Platform-specific permissions handled (Linux `chmod`, Windows registry) -- [ ] Version numbers follow SemVer format -- [ ] Server API deployed with correct version information - ---- - -## Related Resources - -- **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — Patch and config generation tool -- **[Permission Guide](./Permission)** — Windows UAC permission handling -- **[Beginner Cookbook](../quickstart/Beginner%20cookbook)** — Complete update walkthrough -- **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — Core update engine architecture diff --git a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Permission.md b/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Permission.md deleted file mode 100644 index 801da7c..0000000 --- a/website/i18n/en/docusaurus-plugin-content-docs/current/guide/Permission.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 1 ---- - -### Permissions - -#### (1) Windows Platform - -![](imgs/UAC.png) - -When using GeneralUpdate for automatic updates, you may encounter permission issues if the update directory is on the C drive, especially when replacing files or applying patches. With the introduction of Windows 11, permission management for certain directories on the C drive has become more stringent compared to previous Windows operating systems. - -It's important to be aware of which directories might trigger permission issues: - -| Name | Directory | -| --------------- | ------------------------------------------- | -| System Folder | C:\Windows | -| Registry Config | C:\Windows\System32\config | -| Driver Folder | C:\Windows\System32\drivers | -| Program Folder | C:\Program Files and C:\Program Files (x86) | - -Recommended directories to avoid permission issues: - -| Name | Directory | -| -------------------------- | --------- | -| User Data Directory | AppData | -| System Temporary Directory | Temp | - -### Lowering UAC - -The following method is not recommended for use in production environments as it may cause issues for users. If you encounter UAC (User Account Control) prompts or permission/access denied issues during updates, you might consider lowering the UAC control level. This can be done by modifying the registry as follows: - -| Registry Name | New Value | Default Value | -| -------------------------- | --------- | ------------- | -| enableLUA | 0 | 1 | -| ConsentPromptBehaviorAdmin | 0 | 5 | - -Modify the above registry settings before the update (effective after restarting the computer), and be sure to restore them after the update is complete. - -C# code to modify the registry: - -```c# -using Microsoft.Win32; - -public void UpdateRegistry() -{ - const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; - - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) - { - if (key != null) - { - key.SetValue("EnableLUA", 0, RegistryValueKind.DWord); - key.SetValue("ConsentPromptBehaviorAdmin", 0, RegistryValueKind.DWord); - } - } -} -``` - -Batch script to modify the registry: - -```bat -@echo off -REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA /t REG_DWORD /d 0 /f -REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f -``` - -References: -- https://learn.microsoft.com/zh-cn/windows/security/application-security/application-control/user-account-control/how-it-works -- https://blog.walterlv.com/post/windows-user-account-control.html \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md index d490a12..5925874 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Bowl.md @@ -417,4 +417,4 @@ MyApp/ - [Bowl 示例代码](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Bowl) - [GeneralUpdate 仓库](https://github.com/GeneralLibrary/GeneralUpdate) -- [Dump 指南](../guide/Dump) +- [Dump 指南](../guide/Deployment and Operations) diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md index 81e048a..3b3c4a3 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/doc/GeneralUpdate.Extension.md @@ -676,4 +676,4 @@ report-extension_1.0.0.zip - [扩展管理示例](https://github.com/GeneralLibrary/GeneralUpdate-Samples/tree/main/src/Hub/Samples/ExtensionSample.cs) - [GeneralUpdate 仓库](https://github.com/GeneralLibrary/GeneralUpdate) -- [打包指南](../guide/Packaging) +- [打包指南](../guide/Deployment and Operations) diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Deployment and Operations.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Deployment and Operations.md new file mode 100644 index 0000000..26a344a --- /dev/null +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Deployment and Operations.md @@ -0,0 +1,444 @@ +--- +sidebar_position: 1 +--- + +# 部署与运维指南 + +本文档涵盖应用程序打包部署、平台适配、故障排查和运维诊断。 + +--- + +## 一、补丁包生成 + +### 使用 GeneralUpdate.Tools (推荐) + +[GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) 是最推荐的补丁包生成工具,提供可视化界面和完整的验证能力。 + +**操作步骤:** + +1. 下载并启动 GeneralUpdate.Tools +2. 切换到「补丁包」选项卡 +3. 选择旧版本目录(源路径) +4. 选择新版本目录(目标路径) +5. 设置补丁包输出路径 +6. 填写包名和版本号 +7. 点击「构建」 + +详细说明请参考 [GeneralUpdate.Tools 文档](../quickstart/GeneralUpdate.PacketTool)。 + +### 使用 Differential API 编程生成 + +```csharp +using GeneralUpdate.Differential; + +// 生成增量补丁 +var sourcePath = @"C:\Builds\MyApp_v1.0.0"; +var targetPath = @"C:\Builds\MyApp_v1.0.1"; +var patchPath = @"C:\Builds\patches\v1.0.1"; + +await DifferentialCore.Instance.Clean(sourcePath, targetPath, patchPath); + +// 将 patchPath 目录打包为 .zip 上传到服务端 +``` + +--- + +## 二、客户端打包 + +### 文件结构 + +客户端安装目录推荐的结构: + +``` +MyApp/ +├── MyApp.exe ← 主程序 +├── MyApp.Core.dll ← 核心库 +├── UpgradeSample.exe ← 升级助手(与主程序同级) +├── GeneralUpdate.Core.dll ← 升级助手依赖 +├── GeneralUpdate.ClientCore.dll ← 客户端更新组件 +├── GeneralUpdate.Differential.dll +├── generalupdate.manifest.json ← 自动生成的清单文件 +├── appsettings.json ← 应用配置(建议加入黑名单) +└── resources/ + └── ... +``` + +### 客户端引用 + +```xml + + +``` + +```xml + + +``` + +### 升级助手独立项目 + +升级助手(Upgrade)必须是一个**独立的可执行项目**,与主程序分开编译: + +``` +MySolution/ +├── src/ +│ ├── MyApp/ ← 主程序项目 +│ │ ├── MyApp.csproj +│ │ └── Program.cs +│ └── MyApp.Upgrade/ ← 升级助手项目 +│ ├── MyApp.Upgrade.csproj +│ └── Program.cs +└── MySolution.sln +``` + +**升级助手 Program.cs 最小实现:** + +```csharp +using GeneralUpdate.Core; + +await new GeneralUpdateBootstrap() + .AddListenerException((_, args) => + { + Console.WriteLine($"升级异常: {args.Exception.Message}"); + }) + .LaunchAsync(); +``` + +--- + +## 三、平台特定打包 + +### Windows + +**使用 NSIS 创建安装程序:** + +- [NSIS 官网](https://nsis.sourceforge.io/Download) +- NSIS 脚本负责:创建安装目录、复制文件、注册快捷方式 +- 将主程序和升级助手放在同一目录下 +- 确保安装目录对当前用户有写入权限 + +**避免 C 盘权限问题:** + +- 建议默认安装到 `%LOCALAPPDATA%` 而非 `C:\Program Files\` +- 如必须安装在 C 盘,参考下方 [Windows 权限处理](#五windows-权限处理) 章节 + +**Windows 发布命令:** + +```bash +dotnet publish src/MyApp/MyApp.csproj -c Release -r win-x64 --self-contained +dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r win-x64 --self-contained +``` + +### Linux + +**使用 .deb 包 (Debian/Ubuntu):** + +参考 [Avalonia 部署文档](https://docs.avaloniaui.net/docs/deployment/debian-ubuntu) + +**使用 AppImage:** + +通用的 Linux 可移植打包格式,无需安装即可运行。 + +**Linux 权限处理:** + +```csharp +// 在升级助手中使用 UnixPermissionHooks +await new GeneralUpdateBootstrap() + .Hooks() + .LaunchAsync(); +``` + +或使用自定义脚本: + +```csharp +var config = new Configinfo +{ + Script = "/bin/bash chmod -R +x $InstallPath", + // ... +}; +``` + +**Linux 发布命令:** + +```bash +dotnet publish src/MyApp/MyApp.csproj -c Release -r linux-x64 --self-contained +dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r linux-x64 --self-contained +``` + +### macOS + +**使用 .app Bundle:** + +macOS 应用程序通常打包为 `.app` 目录结构。确保升级助手在主程序的 `Contents/MacOS/` 目录中。 + +**代码签名:** + +macOS 要求应用程序经过代码签名才能正常运行(尤其是 Apple Silicon 设备): + +```bash +codesign --deep --force --verify --verbose --sign "Developer ID" MyApp.app +``` + +**公证 (Notarization):** + +分发到 macOS 前,建议提交 Apple 公证: + +```bash +xcrun notarytool submit MyApp.dmg --apple-id your@email.com --wait +``` + +**macOS 发布命令:** + +```bash +dotnet publish src/MyApp/MyApp.csproj -c Release -r osx-x64 --self-contained +dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r osx-x64 --self-contained +``` + +--- + +## 四、CI/CD 集成 + +### GitHub Actions 示例 + +```yaml +name: Build and Package + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: Publish Client + run: dotnet publish src/MyApp/MyApp.csproj -c Release -r win-x64 -o publish/MyApp + + - name: Publish Upgrade + run: dotnet publish src/MyApp.Upgrade/MyApp.Upgrade.csproj -c Release -r win-x64 -o publish/MyApp + + - name: Generate Patch + run: | + # 使用 GeneralUpdate.Tools CLI 或其他脚本生成补丁包 + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: release-package + path: publish/ +``` + +--- + +## 五、Windows 权限处理 + +### UAC 与安装目录 + +![](imgs\UAC.png) + +使用 GeneralUpdate 进行自动更新时,如果更新目录位于 C 盘,尤其在替换文件或应用补丁时可能会遇到权限问题。Windows 11 对 C 盘某些目录的权限管理比以往更加严格。 + +以下目录可能触发权限问题: + +| 名称 | 目录 | +| --- | --- | +| 系统文件夹 | C:\Windows | +| 注册表配置 | C:\Windows\System32\config | +| 驱动文件夹 | C:\Windows\System32\drivers | +| 程序文件夹 | C:\Program Files 和 C:\Program Files (x86) | + +推荐的避免权限问题的目录: + +| 名称 | 目录 | +| --- | --- | +| 用户数据目录 | AppData | +| 系统临时目录 | Temp | + +### 降低 UAC 级别 + +> **警告:** 以下方法不建议在生产环境中使用,可能对用户造成安全风险。 + +如果在更新过程中遇到 UAC 弹窗或权限拒绝问题,可考虑通过修改注册表降低 UAC 控制级别: + +| 注册表项 | 新值 | 默认值 | +| --- | --- | --- | +| enableLUA | 0 | 1 | +| ConsentPromptBehaviorAdmin | 0 | 5 | + +更新前修改以上注册表(重启电脑后生效),更新完成后务必恢复原值。 + +**C# 修改注册表:** + +```csharp +using Microsoft.Win32; + +public void UpdateRegistry() +{ + const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; + + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) + { + if (key != null) + { + key.SetValue("EnableLUA", 0, RegistryValueKind.DWord); + key.SetValue("ConsentPromptBehaviorAdmin", 0, RegistryValueKind.DWord); + } + } +} +``` + +**批处理脚本修改注册表:** + +```bat +@echo off +REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA /t REG_DWORD /d 0 /f +REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f +``` + +**参考链接:** +- [User Account Control 工作原理](https://learn.microsoft.com/zh-cn/windows/security/application-security/application-control/user-account-control/how-it-works) +- [Windows 用户账户控制](https://blog.walterlv.com/post/windows-user-account-control.html) + +--- + +## 六、文件占用排查 + +### Windows 平台 + +即使应用在自动升级前已关闭,在特殊情况下(如后台服务未退出)仍可能出现文件占用。此时可使用微软的 **handle.exe** 工具检查指定目录下是否有进程在运行。 + +`handle.exe` 是 Microsoft Sysinternals 提供的命令行工具,用于显示哪些进程打开了指定文件。在 C# 中可通过 `System.Diagnostics.Process` 调用。 + +```csharp +using System; +using System.Diagnostics; + +class Program +{ + static void Main() + { + Process process = new Process(); + process.StartInfo.FileName = "handle.exe"; + process.StartInfo.Arguments = "filename"; // 替换为实际的文件或目录路径 + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.Start(); + + string output = process.StandardOutput.ReadToEnd(); + Console.WriteLine(output); + + process.WaitForExit(); + } +} +``` + +**如果仍存在文件占用:** +1. 检查是否有后台服务未关闭 +2. 使用 `handle.exe` 排查占用进程 +3. 考虑使用强制终止或重启后更新策略 + +**参考链接:** +- [Handle - Sysinternals](https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle) + +--- + +## 七、崩溃转储诊断 + +在自动更新过程中,如果更新失败或更新后程序崩溃,可使用 **ProcDump** 工具导出 dump 文件进行分析。 + +ProcDump 是 Microsoft Sysinternals 的命令行实用工具,主要用于监控应用程序的 CPU 峰值并在峰值期间生成崩溃转储。管理员或开发人员可使用这些转储来确定崩溃原因。ProcDump 还支持挂起窗口监控、未处理异常监控,并可基于系统性能计数器值生成转储。 + +### C# 调用 ProcDump + +```csharp +using System; +using System.Diagnostics; + +public class Program +{ + public static void Main() + { + var procDumpPath = @"C:\Path\To\procdump.exe"; + var processId = 1234; // 需要 dump 的进程 ID + var dumpFilePath = @"C:\Path\To\dumpfile.dmp"; + + var startInfo = new ProcessStartInfo + { + FileName = procDumpPath, + Arguments = $"-ma {processId} {dumpFilePath}", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + }; + + var process = new Process { StartInfo = startInfo }; + process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data); + process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data); + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + process.WaitForExit(); + } +} +``` + +**参考链接:** +- [ProcDump - Sysinternals](https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump) + +--- + +## 八、版本号管理 + +### 推荐策略 + +| 策略 | 说明 | 适用场景 | +|------|------|----------| +| **手动管理** | 在 `.csproj` 中硬编码 `` | 小型项目 | +| **Git Tag** | 从 Git Tag 读取版本号 | 有 CI/CD 的项目 | +| **MinVer** | 自动从 Git 历史计算版本号 | 推荐 | +| **Nerdbank.GitVersioning** | 精确的 Git 版本管理 | 大型项目 | + +### MinVer 配置示例 + +```xml + + + all + runtime; build; native; contentfiles; analyzers + +``` + +--- + +## 九、部署检查清单 + +部署前确认: + +- [ ] 主程序引用 `GeneralUpdate.ClientCore` +- [ ] 升级助手是独立的可执行项目,引用 `GeneralUpdate.Core` +- [ ] 升级助手与主程序部署在同一目录 +- [ ] `generalupdate.manifest.json` 可通过 Tools 的「配置生成器」自动生成 +- [ ] 已在测试环境使用 Tools 的「模拟更新」功能完整验证 +- [ ] 黑名单配置正确(保护用户数据不被覆盖) +- [ ] 平台特定权限处理已配置(Linux `chmod`、Windows 注册表降权) +- [ ] 版本号符合 SemVer 格式 +- [ ] 服务端 API 已部署并配置正确的版本信息 + +--- + +## 相关资源 + +- **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — 补丁包和配置生成工具 +- **[入门实战手册](../quickstart/Beginner cookbook)** — 从零跑通更新闭环 +- **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — 核心更新引擎架构 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Dump.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Dump.md deleted file mode 100644 index 6b99217..0000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Dump.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 4 ---- - -### Dump 转储文件 - -在自动升级的过程中如果更新失败,或程序更新完成之后运行崩溃都可以使用ProcDump工具辅助导出dump文件。ProcDump 是一个命令行实用工具,其主要用途是监视应用程序的 CPU 峰值,并在出现峰值期间生成故障转储,管理员或开发人员可以使用这些转储来确定出现峰值的原因。 ProcDump 还支持挂起窗口监视(使用与 Windows 和任务管理器使用的窗口挂起相同的定义)、未处理的异常监视,并且可以根据系统性能计数器的值生成转储。 它还可用作可嵌入到其他脚本中的常规进程转储实用工具。 - -##### (1)Windows平台 - -C#实现调用: - -```c# -using System; -using System.Diagnostics; - -public class Program -{ - public static void Main() - { - var procDumpPath = @"C:\Path\To\procdump.exe"; - var processId = 1234; // 您要转储的进程的ID - var dumpFilePath = @"C:\Path\To\dumpfile.dmp"; - - var startInfo = new ProcessStartInfo - { - FileName = procDumpPath, - Arguments = $"-ma {processId} {dumpFilePath}", - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true - }; - - var process = new Process { StartInfo = startInfo }; - process.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data); - process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data); - - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - - process.WaitForExit(); - } -} -``` - - - -参考资料: - -- https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/FAQ.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/FAQ.md deleted file mode 100644 index 3e60d12..0000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/FAQ.md +++ /dev/null @@ -1,338 +0,0 @@ ---- -sidebar_position: 8 ---- - -# 常见问题 (FAQ) - -## 基础概念 - -### Q1: GeneralUpdate 是什么? - -GeneralUpdate 是一个基于 .NET Standard 2.0 的跨平台自动更新框架。它提供了完整的应用程序更新解决方案,包括版本检查、下载管理、二进制差分更新、驱动更新、插件管理等功能。 - -### Q2: ClientCore 和 Core 有什么区别? - -| | ClientCore | Core | -|---|---|---| -| **运行位置** | 主程序进程内 | 独立升级进程 | -| **职责** | 检查更新、下载包、启动升级助手 | 解压、打补丁、替换文件、启动新版本 | -| **依赖方向** | 引用 Core 的共享类型 | 被 ClientCore 启动(通过 IPC) | -| **NuGet 包** | `GeneralUpdate.ClientCore` | `GeneralUpdate.Core` | - -**简单来说:** ClientCore "检查和下载",Core "安装和替换"。 - -### Q3: 什么是差分更新?为什么需要它? - -差分更新只下载两个版本之间的**变化部分**,而不是下载完整的安装包。 - -- **全量更新:** 下载 50MB → 解压 50MB → 覆盖安装 -- **差分更新:** 下载 5MB (补丁) → 解压 → BSDiff 算法合并 → 仅 5MB 下载 - -对于频繁更新的应用,差分更新可节省 80%-95% 的带宽。 - -### Q4: GeneralUpdate 支持哪些平台? - -| 操作系统 | 支持状态 | 备注 | -|----------|----------|------| -| Windows 10/11 | ✅ 完整支持 | 包括 WPF/WinForms/WinUI/Avalonia/Console | -| Linux (Ubuntu/Debian/Fedora) | ✅ 完整支持 | Avalonia/Console | -| macOS | ✅ 完整支持 | Avalonia/Console | -| Android | ✅ 通过 MAUI | 仅 OSS 模式 | -| 麒麟 V10 (飞腾/鲲鹏) | ✅ 已验证 | 国产化平台 | -| 统信 UOS | ✅ 已验证 | 国产化平台 | -| 龙芯 (LoongArch) | ✅ 已验证 | 国产化平台 | - ---- - -## 安装与配置 - -### Q5: 最简配置需要多少代码? - -使用 `ConfiginfoBuilder` 零配置模式: - -```csharp -using GeneralUpdate.ClientCore; -using GeneralUpdate.Common.Shared.Object; - -var config = ConfiginfoBuilder - .Create("https://your-server.com/api/update/check", - "your-token", "Bearer") - .Build(); - -await new GeneralClientBootstrap() - .SetConfig(config) - .LaunchAsync(); -``` - -仅需 3 个参数,其它从 `.csproj` 自动提取。 - -### Q6: 如何配置黑名单? - -```csharp -var config = new Configinfo -{ - // 跳过特定文件 - BlackFiles = new List { "appsettings.json", "userdata.db" }, - - // 跳过特定格式 - BlackFormats = new List { ".log", ".cache", ".tmp" }, - - // 跳过特定目录 - SkipDirectorys = new List { "logs", "temp", "userdata" } -}; -``` - -默认已跳过:`System.*.dll`、`.patch`、`.pdb`、`.rar`、`.tar`、`.json`、`.zip` 文件,以及 `app-`、`fail` 开头的目录。 - -### Q7: 静默更新如何配置? - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.EnableSilentUpdate, true) - .SetConfig(config) - .LaunchAsync(); -``` - -启用后: -- 每 20 分钟(可配置)后台轮询检查新版本 -- 发现新版本后静默下载 -- 主程序退出时自动触发升级 -- 无需用户交互 - ---- - -## 版本管理 - -### Q8: 版本号格式要求是什么? - -使用语义化版本(SemVer 2.0)格式:`Major.Minor.Patch.Build` - -- `1.0.0.0` ✓ -- `2.1.3.5` ✓ -- `1.0` ✗(不完整) -- `v1.0.0` ✗(含前缀) - -### Q9: 如何处理多版本跳级更新? - -GeneralUpdate 自动支持逐版本更新。如果客户端版本是 `1.0.0.0`,服务端有 `1.0.1.0`、`1.0.2.0`、`1.1.0.0` 三个版本: - -``` -客户端 1.0.0.0 - → 下载 patch_v1.0.1.zip → 更新到 1.0.1.0 - → 下载 patch_v1.0.2.zip → 更新到 1.0.2.0 - → 下载 patch_v1.1.0.zip → 更新到 1.1.0.0 -``` - -按发布日期逐个升级,确保每步都经过完整校验。 - -### Q10: 可以实现强制更新吗? - -可以。服务端在版本信息中设置 `IsForcibly: true`: - -```json -{ - "Version": "2.0.0.0", - "IsForcibly": true, - "UpdateLog": "重要安全更新,必须安装" -} -``` - -强制更新时,客户端的 `AddListenerUpdatePrecheck` 回调返回值会被忽略,更新一定执行。 - ---- - -## 下载与网络 - -### Q11: 支持断点续传吗? - -支持。下载中断后,下次启动会从断点继续下载。通过 `EnableResume` 选项控制(默认启用)。 - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.EnableResume, true) - .SetConfig(config) - .LaunchAsync(); -``` - -### Q12: 下载超时如何配置? - -```csharp -await new GeneralClientBootstrap() - .Option(UpdateOption.DownloadTimeOut, 120) // 120 秒超时 - .SetConfig(config) - .LaunchAsync(); -``` - -默认超时 30 秒。建议根据更新包大小和网络环境调整。 - -### Q13: 可以并发下载多个版本吗? - -可以。通过 `MaxConcurrency` 全局选项配置: - -```csharp -Option.MaxConcurrency.SetValue(5); // 最多同时下载 5 个版本 -``` - ---- - -## 差分更新 - -### Q14: 差分更新 vs 全量更新,如何选择? - -| 场景 | 建议模式 | -|------|----------| -| 日常小版本更新 | 差分更新(默认) | -| 大版本跨越(如 1.x → 2.x) | 全量更新 | -| 文件变化 < 20% | 差分更新 | -| 文件变化 > 80% | 全量更新 | -| 首次安装 | 全量更新 | - -```csharp -// 关闭差分更新 -await new GeneralClientBootstrap() - .Option(UpdateOption.Patch, false) - .SetConfig(config) - .LaunchAsync(); -``` - -### Q15: 补丁包是如何生成的? - -使用 [GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) 的「补丁包」功能: - -1. 选择旧版本目录(如 `MyApp_v1.0.0`) -2. 选择新版本目录(如 `MyApp_v1.0.1`) -3. 设置输出目录 -4. 点击「构建」 - -工具自动: -- 对比两个目录的文件差异 -- 为修改的文件生成 BSDiff 补丁(`.patch`) -- 收集新增文件 -- 记录需要删除的文件(`delete_files.json`) -- 打包为 `.zip` - ---- - -## 文件与权限 - -### Q16: 更新时遇到文件被占用怎么办? - -更新过程由独立的升级助手进程(Core)执行,主程序已退出,通常不会有文件占用问题。 - -如果仍有占用: -1. 检查是否有后台服务未关闭 -2. 使用 [文件占用指南](./File occupancy) 中的 `handle.exe` 排查 -3. 考虑使用强制重启后更新策略 - -### Q17: Linux/macOS 上文件权限怎么处理? - -使用 `UnixPermissionHooks` 或 `CustomPermissionHooks`: - -```csharp -// 自动 chmod +x -await new GeneralClientBootstrap() - .Hooks() - .SetConfig(config) - .LaunchAsync(); -``` - -或通过 `Configinfo.Script` 指定自定义脚本: - -```csharp -var config = new Configinfo -{ - Script = "/path/to/permission-script.sh", - // ... -}; -``` - ---- - -## 故障排查 - -### Q18: 更新失败如何诊断? - -1. **检查事件监听:** 确保注册了所有异常和错误监听器 -2. **查看 Bowl 日志:** 如果启用了 Bowl,检查 `fail/` 目录下的 Dump 和诊断文件 -3. **检查服务端日志:** 确认版本信息正确返回 -4. **检查网络:** 确认客户端可以访问服务端 API 和下载地址 -5. **检查版本号:** 确保客户端和服务端的版本号格式一致 - -### Q19: 如何实现回滚? - -GeneralUpdate 有自动备份和回滚机制: - -```csharp -// 确保启用备份 -await new GeneralClientBootstrap() - .Option(UpdateOption.BackUp, true) - .SetConfig(config) - .LaunchAsync(); -``` - -更新失败或 Bowl 检测到崩溃时,自动从备份目录恢复文件。 - -### Q20: 如何在开发环境测试更新流程? - -使用 [GeneralUpdate.Tools](https://github.com/GeneralLibrary/GeneralUpdate.Tools) 的「模拟更新」功能: - -1. 选择应用程序目录和补丁包 -2. 设置版本号和平台 -3. 点击「开始模拟」 - -工具自动: -- 启动本地模拟服务端 -- 发布并运行 ClientSample 和 UpgradeSample -- 执行完整更新流程 -- 生成测试报告 - ---- - -## 服务端 - -### Q21: 服务端 API 需要自己实现吗? - -示例项目中提供了简单的服务端示例。生产环境需要自行实现或使用商业版本 [GeneralSpacestation](https://www.justerzhu.cn/)。 - -**需要实现的 API:** -1. `POST /Upgrade/Verification` — 版本验证 -2. `POST /Upgrade/Report` — 状态上报 -3. `GET /patch/{filename}` — 补丁包下载 - -### Q22: 可以和 CI/CD 集成吗? - -可以。推荐集成方式: - -1. **CI 构建:** 编译新旧版本 -2. **Tools 命令行:** 使用 GeneralUpdate.Tools 生成补丁包(CLI 模式) -3. **上传:** 将补丁包和 `version.json` 上传到服务器/OSS -4. **更新清单:** 更新服务端版本数据库 - ---- - -## OSS 模式 - -### Q23: OSS 模式和标准模式有什么区别? - -| | 标准模式 | OSS 模式 | -|---|---|---| -| **服务端** | 需要 HTTP API 服务 | 仅需对象存储(S3/OSS/MinIO) | -| **版本检查** | API 调用 | 读取 `version.json` 文件 | -| **适用场景** | 有后端服务的应用 | 客户端工具、桌面软件 | -| **成本** | 需要维护服务 | 仅存储和流量费用 | - -### Q24: 如何从标准模式迁移到 OSS 模式? - -1. 生成 `version.json`(使用 GeneralUpdate.Tools OSS 配置模块) -2. 将 `version.json` 和补丁包上传到对象存储 -3. 客户端修改 `AppType` 为 `OssClient` -4. 配置 OSS 地址 - ---- - -## 相关资源 - -- **[GeneralUpdate.Core](../doc/GeneralUpdate.Core)** — 核心更新引擎 -- **[入门实战手册](../quickstart/Beginner%20cookbook)** — 从零跑通更新闭环 -- **[GeneralUpdate.Tools](../quickstart/GeneralUpdate.PacketTool)** — 打包工具 -- **[GeneralUpdate.Bowl](../doc/GeneralUpdate.Bowl)** — 崩溃监控与回滚 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/File occupancy.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/File occupancy.md deleted file mode 100644 index a5d28e1..0000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/File occupancy.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -sidebar_position: 2 ---- - -### File occupancy 文件占用 - -#### (1)Windows平台 - -虽然在自动升级时会关闭应用程序,如果出现特殊情况出现文件占用通常是进程还在运行导致的。这时候可以使用微软官方提供的handle.exe检测工具来查看指定目录下是否有进程在运行"handle.exe"是一款由微软提供的命令行工具,可以用来显示哪些进程打开了哪些文件。在C#中调用handle.exe,我们可以使用`System.Diagnostics.Process`类,如果检测到则会返回该目录下正在运行的进程列表。 - -```c# -using System; -using System.Diagnostics; - -class Program -{ - static void Main() - { - Process process = new Process(); - process.StartInfo.FileName = "handle.exe"; - process.StartInfo.Arguments = "filename"; - process.StartInfo.UseShellExecute = false; - process.StartInfo.RedirectStandardOutput = true; - process.Start(); - - string output = process.StandardOutput.ReadToEnd(); - Console.WriteLine(output); - - process.WaitForExit(); - } -} -``` - - - -参考资料: - -- https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Packaging.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Packaging.md deleted file mode 100644 index 2f21d9a..0000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Packaging.md +++ /dev/null @@ -1,13 +0,0 @@ -# Packaging - - - -## Windows - -- https://nsis.sourceforge.io/Download - - - -## Linux - -- https://docs.avaloniaui.net/docs/deployment/debian-ubuntu \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Permission.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Permission.md deleted file mode 100644 index 4789c2b..0000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/guide/Permission.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -sidebar_position: 1 ---- - -### Permission 权限 - -#### (1)Windows平台 - -![](imgs\UAC.png) - -在使用GeneralUpdate实现自动升级的时候,如果更新目录在C盘实现文件替换或打文件补丁时会出现权限问题。又因为windows11操作系统推出在C盘特定的目录相比之前推出的windows的操作系统加强了权限管理。 - -那么稍微不注意将会触碰到权限管理的边界,接下来我们看看操作哪些目录会导致出现权限问题: - -| 名称 | 目录 | -| -------------- | ------------------------------------------ | -| 系统文件夹 | C:\Windows | -| 注册表配置文件 | C:\Windows\System32\config | -| 驱动文件夹 | C:\Windows\System32\drivers | -| 程序文件夹 | C:\Program Files 和 C:\Program Files (x86) | - -推荐使用目录,避免权限问题: - -| 名称 | 目录 | -| ------------ | ------- | -| 用户数据目录 | AppData | -| 系统临时目录 | Temp | - - - -### UAC降权 - -以下方法不推荐在生产环境中使用,以免给用户造成损失。如果在更新过程中出现UAC (User Account Control)提示或无权限、拒绝访问的情况可以考虑降低UAC控制等级,这个思路在代码层面可以通过修改以下注册表达到目的: - -| 注册表名称 | 修改值 | 默认值 | -| -------------------------- | ------ | ------ | -| enableLUA | 0 | 1 | -| ConsentPromptBehaviorAdmin | 0 | 5 | - -更新之前修改以上注册表(重启计算机生效),切记更新完成之后需要恢复该内容。 - - - -c#修改注册表: - -```c# -using Microsoft.Win32; - -public void UpdateRegistry() -{ - const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"; - - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) - { - if (key != null) - { - key.SetValue("EnableLUA", 0, RegistryValueKind.DWord); - key.SetValue("ConsentPromptBehaviorAdmin", 0, RegistryValueKind.DWord); - } - } -} -``` - - - -bat批处理修改注册表: - -```bat -@echo off -REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA /t REG_DWORD /d 0 /f -REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f -``` - - - -参考资料: - -- https://learn.microsoft.com/zh-cn/windows/security/application-security/application-control/user-account-control/how-it-works -- https://blog.walterlv.com/post/windows-user-account-control.html \ No newline at end of file diff --git a/website/sidebars.js b/website/sidebars.js index 98dc475..c41bb51 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -43,7 +43,7 @@ const sidebars = { // ── 3. Help ───────────────────────────────────────────────────── { type: 'category', - label: '帮助', + label: '部署与运维', collapsed: true, items: [ { type: 'autogenerated', dirName: 'guide' },