mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-21 08:04:26 +08:00
feat.尝试弄了AOT的启动器。
This commit is contained in:
178
docs/AOT_PUBLISH.md
Normal file
178
docs/AOT_PUBLISH.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# Launcher AOT 单文件发布指南
|
||||
|
||||
## 什么是 AOT?
|
||||
|
||||
AOT(Ahead-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)
|
||||
78
docs/HOST_DISCOVERY.md
Normal file
78
docs/HOST_DISCOVERY.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# 主程序发现配置指南
|
||||
|
||||
Launcher 支持灵活的主程序发现机制,可以通过多种方式配置主程序路径。
|
||||
|
||||
## 发现优先级
|
||||
|
||||
1. **环境变量** (`LMD_HOST_PATH`) - 最高优先级
|
||||
2. **配置文件** (`host-discovery.json`)
|
||||
3. **开发模式保存的路径** - 通过调试窗口选择
|
||||
4. **部署目录** (`app-*`)
|
||||
5. **开发路径** - 自动搜索解决方案中的 bin 目录
|
||||
6. **额外配置路径** - 自定义搜索路径
|
||||
7. **递归搜索** - 如果启用
|
||||
|
||||
## 配置方式
|
||||
|
||||
### 1. 环境变量
|
||||
|
||||
设置 `LMD_HOST_PATH` 环境变量指向主程序可执行文件:
|
||||
|
||||
```powershell
|
||||
$env:LMD_HOST_PATH = "C:\MyApp\LanMountainDesktop.exe"
|
||||
```
|
||||
|
||||
### 2. 配置文件
|
||||
|
||||
在应用根目录创建 `host-discovery.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"HostPath": "C:\\Custom\\Path\\LanMountainDesktop.exe",
|
||||
"AdditionalPaths": [
|
||||
"${AppRoot}/custom",
|
||||
"${UserProfile}/dev/build",
|
||||
"C:/Program Files/LanMountainDesktop/*"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 开发模式
|
||||
|
||||
在错误窗口中按 `Ctrl+Shift+D` 打开调试窗口,启用开发模式并选择自定义路径。路径会自动保存,下次启动时优先使用。
|
||||
|
||||
## 路径变量
|
||||
|
||||
配置文件支持以下变量:
|
||||
|
||||
- `${AppRoot}` - 应用根目录
|
||||
- `${BaseDirectory}` - Launcher 所在目录
|
||||
- `${UserProfile}` - 用户主目录
|
||||
- `${LocalAppData}` - 本地应用数据目录
|
||||
|
||||
## 通配符支持
|
||||
|
||||
`AdditionalPaths` 支持通配符:
|
||||
|
||||
```json
|
||||
{
|
||||
"AdditionalPaths": [
|
||||
"C:/Builds/*/LanMountainDesktop.exe",
|
||||
"${AppRoot}/versions/*/app.exe"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 递归搜索
|
||||
|
||||
启用递归搜索可以自动在子目录中查找主程序:
|
||||
|
||||
```csharp
|
||||
var options = new HostDiscoveryOptions
|
||||
{
|
||||
RecursiveSearch = true,
|
||||
MaxRecursionDepth = 3
|
||||
};
|
||||
```
|
||||
|
||||
注意:递归搜索可能影响启动性能,建议仅在必要时启用。
|
||||
129
docs/LAUNCHER_DISTRIBUTION.md
Normal file
129
docs/LAUNCHER_DISTRIBUTION.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Launcher 打包分发指南
|
||||
|
||||
## 目录结构
|
||||
|
||||
打包给用户的 Launcher 应该包含以下结构:
|
||||
|
||||
```
|
||||
LanMountainDesktop/
|
||||
├── LanMountainDesktop.Launcher.exe # 启动器可执行文件
|
||||
├── LanMountainDesktop.Launcher.dll # 启动器依赖
|
||||
├── ... # 其他启动器依赖文件
|
||||
├── app-1.0.0/ # 主程序部署目录
|
||||
│ ├── LanMountainDesktop.exe # 主程序可执行文件
|
||||
│ ├── LanMountainDesktop.dll # 主程序依赖
|
||||
│ ├── version.json # 版本信息文件
|
||||
│ └── .current # 当前版本标记文件
|
||||
└── plugins/ # 插件目录(可选)
|
||||
```
|
||||
|
||||
## 打包步骤
|
||||
|
||||
### 1. 构建 Launcher
|
||||
|
||||
```bash
|
||||
dotnet build LanMountainDesktop.Launcher/LanMountainDesktop.Launcher.csproj -c Release
|
||||
```
|
||||
|
||||
### 2. 构建主程序
|
||||
|
||||
```bash
|
||||
dotnet build LanMountainDesktop/LanMountainDesktop.csproj -c Release
|
||||
```
|
||||
|
||||
### 3. 创建部署目录
|
||||
|
||||
```powershell
|
||||
# 创建版本目录
|
||||
New-Item -ItemType Directory -Path "dist/app-1.0.0" -Force
|
||||
|
||||
# 复制主程序文件
|
||||
Copy-Item "LanMountainDesktop/bin/Release/net10.0/*" "dist/app-1.0.0/" -Recurse
|
||||
|
||||
# 创建版本标记
|
||||
New-Item -ItemType File -Path "dist/app-1.0.0/.current" -Force
|
||||
```
|
||||
|
||||
### 4. 复制 Launcher
|
||||
|
||||
```powershell
|
||||
# 复制启动器文件
|
||||
Copy-Item "LanMountainDesktop.Launcher/bin/Release/net10.0/*" "dist/" -Recurse
|
||||
```
|
||||
|
||||
### 5. 创建安装包
|
||||
|
||||
可以使用以下工具创建安装包:
|
||||
- **Inno Setup** - Windows 安装程序
|
||||
- **WiX Toolset** - Windows Installer
|
||||
- **MSIX** - Windows 应用包
|
||||
- **Zip** - 便携版
|
||||
|
||||
## 用户数据存储位置
|
||||
|
||||
Launcher 会将用户配置存储在以下位置:
|
||||
|
||||
```
|
||||
%LOCALAPPDATA%\LanMountainDesktop\.launcher\
|
||||
├── devmode.config # 开发模式状态
|
||||
└── custom-host-path.config # 自定义主程序路径
|
||||
```
|
||||
|
||||
这些文件:
|
||||
- **不会**随应用更新而删除
|
||||
- **不会**随应用卸载而删除(除非用户手动清理)
|
||||
- 在重装应用后会自动恢复之前的配置
|
||||
|
||||
## 生产环境行为
|
||||
|
||||
### 正常启动流程
|
||||
|
||||
1. 用户双击 `LanMountainDesktop.Launcher.exe`
|
||||
2. Launcher 查找 `app-*` 目录中的主程序
|
||||
3. 启动主程序并传递版本信息
|
||||
4. 主程序显示正确的版本和开发代号
|
||||
|
||||
### 更新流程
|
||||
|
||||
1. 新版本下载到 `app-{new-version}/`
|
||||
2. 创建 `.current` 标记指向新版本
|
||||
3. 旧版本标记为 `.destroy`
|
||||
4. 下次启动时自动使用新版本
|
||||
|
||||
## 开发环境配置
|
||||
|
||||
### 启用开发模式
|
||||
|
||||
1. 启动 Launcher,如果找不到主程序会显示错误窗口
|
||||
2. 按 `Ctrl+Shift+D` 打开调试窗口
|
||||
3. 勾选"启用开发模式"
|
||||
4. 选择自定义主程序路径
|
||||
5. 关闭窗口,配置会自动保存
|
||||
|
||||
### 开发模式优先级
|
||||
|
||||
开发模式的配置**不会**影响生产环境:
|
||||
- 生产环境优先使用 `app-*` 目录
|
||||
- 开发模式仅在找不到部署目录时生效
|
||||
- 开发模式配置保存在用户数据目录,不影响其他用户
|
||||
|
||||
## 故障排除
|
||||
|
||||
### Launcher 找不到主程序
|
||||
|
||||
1. 检查 `app-*` 目录是否存在
|
||||
2. 检查 `.current` 标记文件是否存在
|
||||
3. 检查主程序可执行文件是否存在
|
||||
4. 查看 `%LOCALAPPDATA%\LanMountainDesktop\.launcher\` 下的配置
|
||||
|
||||
### 版本信息不正确
|
||||
|
||||
1. 检查 `app-*/version.json` 是否存在
|
||||
2. 检查 `version.json` 内容是否正确
|
||||
3. 重新构建主程序生成新的 `version.json`
|
||||
|
||||
### 开发模式配置丢失
|
||||
|
||||
1. 检查 `%LOCALAPPDATA%\LanMountainDesktop\.launcher\` 目录权限
|
||||
2. 检查磁盘空间是否充足
|
||||
3. 手动删除配置目录后重新配置
|
||||
Reference in New Issue
Block a user