Files
LanMountainDesktop/docs/AOT_PUBLISH.md
lincube 4cb52e56c7 Launcher (#4)
* 激进的更新

* 试试

* fix.可爱的我一直在修CI(

* fix.启动器一定要能够启动

* feat.尝试弄了AOT的启动器。

* fix.修CI,好像是因为Linux那边有个问题,反正修就对了。

* fix.ci难修,为什么liunx跑不起来呢?

* Update build.yml

* Update LanMountainDesktop.csproj

* changed.调整了启动逻辑,优化了更新页面。

* changed.优化了更新体验

* feat.依旧试增量更新这一块,看看velopack

* fix.我们试验性地修复了启动器无法正常启动的问题,原因可能是这个画面没有启动,就GUI没显示。然后还把编译问题修了一下。

* fix.继续修ci,ci怎么天天炸

* changed.velopack,试试rust

* fix.修ci,修融合桌面,修启动器

* fix.GitHub Action工作流怎么天天出问题

* feat.引入velopack,不好,是rust(至少内存很安全了。

* chore: migrate release pipeline to signed filemap and wire rainyun s3

* fix: make optional s3 upload step workflow-parse safe

* fix: make delta pack generation robust for empty diffs and linux paths

* chore: rotate launcher update public key for pdc signing

* fix: restore stable launcher update public key

* fix: sync launcher public key with update signing secret

* fix: normalize PEM line endings in signing key validation

* fix: rotate launcher public key to match ci signing secret

* fix: compare signing keys by SPKI instead of PEM text

* refactor update backend to host-managed PDC pipeline

* fix release workflow env key collisions

* relax publish-pdc precheck to require S3 only

* set GH_TOKEN for PDCC installer step

* ci: add local pdc mock fallback for release publish

* ci: fix pdc mock process log redirection

* ci: fallback pdcc signing key to update private key

* ci: ensure pdcc signing passphrase env is always set

* ci: create pdcc publish root before invoking client

* ci: set pdcc version variable from release version

* ci: decouple pdcc installer version from publish config version

* ci: package pdcc subchannels with generated filemap and changelog

* ci: make local pdc mock diff return empty for fast fallback

* ci: fix pdcc variable mapping and pdc signing prechecks

* Update App.axaml.cs

* ci: wire aws cli credentials for rainyun s3

* ci: pin pdcc client version separately from app version

* ci: harden local pdc mock transport handling

* ci: publish pdcc subchannels in one pass

* ci: add pdcc publish heartbeat and timeout

* ci: fix pdcc publish workdir bootstrap

* feat.Penguin Logistics Online Network Distribution System

* ci: fix plonds s3 probe and signing fallback

* ci: validate signing key and quiet missing baselines

* ci: relax aws checksum mode for rainyun s3

* ci: avoid multipart uploads to rainyun s3

* ci: handle empty plonds baselines safely

* ci.plonds

* Rebuild release pipeline around PLONDS and DDSS

* Fix Windows installer script path in release workflow
2026-04-21 20:59:52 +08:00

179 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Launcher AOT 单文件发布指南
## 什么是 AOT
AOTAhead-of-Time编译将 .NET 代码在构建时直接编译为本地机器码,而不是在运行时通过 JIT 编译。
### AOT 的优势
| 特性 | JIT 模式 | AOT 模式 |
|------|---------|---------|
| 启动速度 | 慢(需要编译) | 快(直接执行) |
| 依赖文件 | 多(.dll, runtimeconfig.json | 少(单文件) |
| 需要 .NET Runtime | 是 | 否 |
| 文件体积 | 小 | 稍大(但单文件更方便) |
| 反编译难度 | 容易 | 困难 |
## 发布方式
### 方式一:使用 PowerShell 脚本(推荐)
```powershell
# 默认发布win-x64单文件自包含
.\scripts\Publish-AOT.ps1
# 指定运行时
.\scripts\Publish-AOT.ps1 -RuntimeIdentifier win-x64
# 不压缩(体积更大但启动更快)
.\scripts\Publish-AOT.ps1 -Compress:$false
```
### 方式二:使用 dotnet CLI
```bash
# 基本 AOT 发布
dotnet publish LanMountainDesktop.Launcher/LanMountainDesktop.Launcher.csproj `
-c Release `
-r win-x64 `
--self-contained `
-p:PublishAot=true `
-p:PublishSingleFile=true `
-p:EnableCompressionInSingleFile=true
# 输出目录
# bin/Release/net10.0/win-x64/publish/
```
### 方式三:使用 MSBuild
```bash
msbuild LanMountainDesktop.Launcher/LanMountainDesktop.Launcher.csproj `
/t:Publish `
/p:Configuration=Release `
/p:RuntimeIdentifier=win-x64 `
/p:PublishAot=true `
/p:PublishSingleFile=true
```
## 支持的运行时
| 运行时标识符 | 说明 |
|-------------|------|
| `win-x64` | Windows 64位推荐 |
| `win-x86` | Windows 32位 |
| `win-arm64` | Windows ARM64 |
| `linux-x64` | Linux 64位 |
| `linux-arm64` | Linux ARM64 |
| `osx-x64` | macOS 64位 |
| `osx-arm64` | macOS ARM64 (Apple Silicon) |
## 文件体积对比
### 普通发布(非 AOT
```
LanMountainDesktop.Launcher.exe 150 KB
LanMountainDesktop.Launcher.dll 200 KB
Avalonia.dll 1.2 MB
...(数十个依赖文件)
总计: ~15 MB
```
### AOT 单文件发布
```
LanMountainDesktop.Launcher.exe 8-12 MB单文件包含所有依赖
```
## 注意事项
### 1. 修剪Trimming
AOT 会自动移除未使用的代码以减小体积。某些反射代码可能需要特殊处理:
```csharp
// 如果类型被反射使用,需要保留
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public class MyClass { }
```
### 2. Avalonia 兼容性
- ✅ Avalonia 11.x 完全支持 AOT
- ✅ 使用 Compiled Bindings已在项目中启用
- ✅ 避免动态 XAML 加载
### 3. Json 序列化
使用 `JsonSerializer` 时需要源生成器:
```csharp
[JsonSerializable(typeof(MyType))]
internal partial class MyJsonContext : JsonSerializerContext { }
```
### 4. 单文件特殊处理
某些文件需要嵌入到单文件中:
```xml
<ItemGroup>
<EmbeddedResource Include="Assets\logo.ico" />
</ItemGroup>
```
## 故障排除
### 发布失败
1. **检查 .NET SDK 版本**
```bash
dotnet --version # 需要 10.0 或更高
```
2. **安装 AOT 工作负载**
```bash
dotnet workload install wasm-tools # 如果需要 WebAssembly AOT
```
3. **Visual Studio 要求**
- 需要 VS 2022 17.8+ 或 VS Code + C# Dev Kit
### 运行时错误
1. **缺少类型**
- 在 `.csproj` 中添加 `<TrimmerRootAssembly>`
2. **反射失败**
- 使用 `[DynamicallyAccessedMembers]` 标记
3. **DllNotFoundException**
- 确保所有 native 库都包含在发布中
## 性能对比
| 指标 | JIT | AOT | 提升 |
|------|-----|-----|------|
| 启动时间 | 2-3 秒 | 0.5-1 秒 | 2-3x |
| 内存占用 | 较高 | 较低 | 20-30% |
| 首次响应 | 慢 | 快 | 显著 |
## 推荐配置
对于 Launcher 项目,推荐使用以下配置:
```xml
<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
```
这样发布的结果:
- ✅ 单文件可执行
- ✅ 无需 .NET Runtime
- ✅ 启动速度快
- ✅ 文件体积合理8-12 MB