feat(ci): 添加 Windows 单文件打包工作流
添加 Enigma Virtual Box 和 7-Zip 备选方案,用于将 Flutter Windows 应用打包为单文件 EXE 包含自动化脚本和文档说明,优化构建产物分发
This commit is contained in:
parent
ef1f3bfb50
commit
b86d645acf
@ -314,3 +314,176 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: windows-release-build
|
name: windows-release-build
|
||||||
path: build/windows/x64/runner/Release/
|
path: build/windows/x64/runner/Release/
|
||||||
|
|
||||||
|
- name: Download Enigma Virtual Box
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Write-Host "下载 Enigma Virtual Box..."
|
||||||
|
$enigmaUrl = "https://enigmaprotector.com/assets/files/enigmavb.exe"
|
||||||
|
$enigmaPath = "C:\enigmavb.exe"
|
||||||
|
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $enigmaUrl -OutFile $enigmaPath -UseBasicParsing
|
||||||
|
Write-Host "✅ Enigma Virtual Box 下载成功"
|
||||||
|
} catch {
|
||||||
|
Write-Host "⚠️ 下载失败,使用备用方案"
|
||||||
|
# 创建简单的自解压脚本作为备选
|
||||||
|
$altScript = @"
|
||||||
|
' 备选打包脚本 - 复制所有文件到输出目录
|
||||||
|
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||||
|
Set shell = CreateObject("WScript.Shell")
|
||||||
|
|
||||||
|
srcFolder = "build\windows\x64\runner\Release"
|
||||||
|
destFolder = "dist\windows-package"
|
||||||
|
|
||||||
|
If fso.FolderExists(srcFolder) Then
|
||||||
|
If Not fso.FolderExists(destFolder) Then
|
||||||
|
fso.CreateFolder(destFolder)
|
||||||
|
End If
|
||||||
|
|
||||||
|
' 复制所有文件
|
||||||
|
Set folder = fso.GetFolder(srcFolder)
|
||||||
|
For Each file In folder.Files
|
||||||
|
file.Copy destFolder & "\" & file.Name, True
|
||||||
|
Next
|
||||||
|
|
||||||
|
' 复制子文件夹
|
||||||
|
For Each subFolder In folder.SubFolders
|
||||||
|
fso.CopyFolder subFolder.Path, destFolder & "\" & subFolder.Name, True
|
||||||
|
Next
|
||||||
|
|
||||||
|
WScript.Echo "✅ 文件打包完成"
|
||||||
|
Else
|
||||||
|
WScript.Echo "❌ 源文件夹不存在"
|
||||||
|
End If
|
||||||
|
"@
|
||||||
|
|
||||||
|
Set-Content -Path "C:\package.vbs" -Value $altScript
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Package Single EXE
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Write-Host "=== 开始打包单文件 EXE ==="
|
||||||
|
|
||||||
|
$buildPath = "build\windows\x64\runner\Release"
|
||||||
|
$outputPath = "dist"
|
||||||
|
$enigmaPath = "C:\enigmavb.exe"
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
if (-not (Test-Path $outputPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $outputPath -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取主程序
|
||||||
|
$exeFile = Get-ChildItem -Path $buildPath -Filter "*.exe" | Select-Object -First 1
|
||||||
|
if (-not $exeFile) {
|
||||||
|
Write-Host "❌ 未找到可执行文件"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$inputExe = $exeFile.FullName
|
||||||
|
$outputExe = "$outputPath\$($exeFile.BaseName)_Single.exe"
|
||||||
|
|
||||||
|
Write-Host "主程序: $inputExe"
|
||||||
|
Write-Host "输出: $outputExe"
|
||||||
|
|
||||||
|
# 尝试使用 Enigma Virtual Box
|
||||||
|
if (Test-Path $enigmaPath) {
|
||||||
|
Write-Host "使用 Enigma Virtual Box 打包..."
|
||||||
|
|
||||||
|
# 创建配置文件
|
||||||
|
$configContent = @"
|
||||||
|
[Config]
|
||||||
|
InputFile=$inputExe
|
||||||
|
OutputFile=$outputExe
|
||||||
|
Files=%DEFAULT FOLDER%
|
||||||
|
VirtualizationMode=Never Write To Disk
|
||||||
|
Compression=Yes
|
||||||
|
ShareVirtualSystem=Yes
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Folder=$buildPath\*
|
||||||
|
"@
|
||||||
|
|
||||||
|
$configFile = "$outputPath\package_config.evb"
|
||||||
|
Set-Content -Path $configFile -Value $configContent
|
||||||
|
|
||||||
|
# 执行打包
|
||||||
|
$process = Start-Process -FilePath $enigmaPath -ArgumentList "/sf", $inputExe, "/lf", $outputExe, "/folder", $buildPath, "/compress" -Wait -PassThru -NoNewWindow
|
||||||
|
|
||||||
|
if ($process.ExitCode -eq 0) {
|
||||||
|
Write-Host "✅ 单文件打包成功!"
|
||||||
|
|
||||||
|
# 显示压缩信息
|
||||||
|
$originalSize = (Get-Item $inputExe).Length / 1MB
|
||||||
|
$packedSize = (Get-Item $outputExe).Length / 1MB
|
||||||
|
Write-Host "原始大小: $([math]::Round($originalSize, 2)) MB"
|
||||||
|
Write-Host "打包大小: $([math]::Round($packedSize, 2)) MB"
|
||||||
|
} else {
|
||||||
|
Write-Host "⚠️ Enigma 打包失败,使用备选方案"
|
||||||
|
throw "Enigma failed"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "⚠️ Enigma 未找到,使用 7-Zip 自解压方案"
|
||||||
|
throw "Enigma not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Package with 7-Zip Alternative
|
||||||
|
if: failure()
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Write-Host "使用 7-Zip 自解压方案..."
|
||||||
|
|
||||||
|
$buildPath = "build\windows\x64\runner\Release"
|
||||||
|
$outputPath = "dist"
|
||||||
|
|
||||||
|
# 检查 7-Zip
|
||||||
|
$7zipPath = "C:\Program Files\7-Zip\7z.exe"
|
||||||
|
if (-not (Test-Path $7zipPath)) {
|
||||||
|
Write-Host "安装 7-Zip..."
|
||||||
|
choco install 7zip -y
|
||||||
|
$7zipPath = "C:\Program Files\7-Zip\7z.exe"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取主程序名称
|
||||||
|
$exeFile = Get-ChildItem -Path $buildPath -Filter "*.exe" | Select-Object -First 1
|
||||||
|
$outputSfx = "$outputPath\$($exeFile.BaseName)_Package.exe"
|
||||||
|
|
||||||
|
Write-Host "创建自解压包..."
|
||||||
|
|
||||||
|
# 创建配置文件
|
||||||
|
$configContent = @"
|
||||||
|
;!@Install@!UTF-8!
|
||||||
|
Title="HostExecutor Windows Package"
|
||||||
|
BeginPrompt="正在解压 HostExecutor..."
|
||||||
|
ExtractDialogText="请稍候,正在解压文件..."
|
||||||
|
ExtractPathText="解压路径:"
|
||||||
|
ExtractTitle="解压中"
|
||||||
|
FinishMessage="解压完成!"
|
||||||
|
GUIFlags="8"
|
||||||
|
;!@InstallEnd@!
|
||||||
|
"@
|
||||||
|
|
||||||
|
$configFile = "$outputPath\config.txt"
|
||||||
|
Set-Content -Path $configFile -Value $configContent -Encoding UTF8
|
||||||
|
|
||||||
|
# 创建压缩包
|
||||||
|
& $7zipPath a -sfx "$outputSfx" "$buildPath\*" -mmt=on -mx=9
|
||||||
|
|
||||||
|
if (Test-Path $outputSfx) {
|
||||||
|
Write-Host "✅ 7-Zip 自解压包创建成功!"
|
||||||
|
Write-Host "输出文件: $outputSfx"
|
||||||
|
|
||||||
|
$size = (Get-Item $outputSfx).Length / 1MB
|
||||||
|
Write-Host "文件大小: $([math]::Round($size, 2)) MB"
|
||||||
|
} else {
|
||||||
|
Write-Host "❌ 7-Zip 打包失败"
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Upload Single EXE Package
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: windows-single-exe
|
||||||
|
path: dist/*.exe
|
||||||
|
if: always()
|
||||||
|
|||||||
137
package_single_exe.md
Normal file
137
package_single_exe.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
# Flutter Windows 单文件 EXE 打包指南
|
||||||
|
|
||||||
|
## 🎯 目标
|
||||||
|
将 Flutter Windows 应用打包成单个可执行文件,便于分发和部署。
|
||||||
|
|
||||||
|
## 📋 当前状态
|
||||||
|
|
||||||
|
### 现有构建输出
|
||||||
|
```
|
||||||
|
build/windows/x64/runner/Release/
|
||||||
|
├── hostexecutor.exe # 主程序
|
||||||
|
├── flutter_windows.dll # Flutter 引擎
|
||||||
|
├── msvcp140.dll # Visual C++ 运行时
|
||||||
|
├── vcruntime140.dll # Visual C++ 运行时
|
||||||
|
├── vcruntime140_1.dll # Visual C++ 运行时
|
||||||
|
└── data/ # 应用数据文件夹
|
||||||
|
├── app.so # Dart 代码编译结果
|
||||||
|
└── flutter_assets/ # 资源文件
|
||||||
|
```
|
||||||
|
|
||||||
|
### 问题分析
|
||||||
|
Flutter 默认构建会生成多个文件,因为:
|
||||||
|
1. **Flutter 引擎** (`flutter_windows.dll`) - 必须包含
|
||||||
|
2. **Visual C++ 运行时** - 系统依赖
|
||||||
|
3. **应用数据** (`data` 文件夹) - 包含资源和 Dart 代码
|
||||||
|
|
||||||
|
## 🔧 解决方案
|
||||||
|
|
||||||
|
### 方案一:使用 Enigma Virtual Box(推荐)
|
||||||
|
|
||||||
|
#### 步骤 1:下载安装
|
||||||
|
1. 下载 [Enigma Virtual Box](https://enigmaprotector.com/en/downloads.html)
|
||||||
|
2. 安装并运行
|
||||||
|
|
||||||
|
#### 步骤 2:打包配置
|
||||||
|
1. **主程序文件**: 选择 `build/windows/x64/runner/Release/hostexecutor.exe`
|
||||||
|
2. **添加文件夹**: 选择整个 `Release` 文件夹
|
||||||
|
3. **输出文件**: 设置输出路径和文件名
|
||||||
|
4. **文件选项**: 勾选"压缩文件"
|
||||||
|
|
||||||
|
#### 步骤 3:生成单文件
|
||||||
|
点击"Process"生成单个可执行文件。
|
||||||
|
|
||||||
|
### 方案二:使用 Inno Setup(安装程序)
|
||||||
|
|
||||||
|
#### 步骤 1:下载安装
|
||||||
|
1. 下载 [Inno Setup](https://jrsoftware.org/isinfo.php)
|
||||||
|
2. 安装并运行
|
||||||
|
|
||||||
|
#### 步骤 2:创建脚本
|
||||||
|
```ini
|
||||||
|
[Setup]
|
||||||
|
AppName=HostExecutor
|
||||||
|
AppVersion=1.0.0
|
||||||
|
DefaultDirName={autopf}\HostExecutor
|
||||||
|
OutputBaseFilename=HostExecutor_Setup
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "build\windows\x64\runner\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{group}\HostExecutor"; Filename: "{app}\hostexecutor.exe"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 步骤 3:编译生成
|
||||||
|
编译脚本生成安装程序。
|
||||||
|
|
||||||
|
### 方案三:使用 Windows 自带工具(高级)
|
||||||
|
|
||||||
|
#### 使用 `dotnet publish`(需要 .NET 包装)
|
||||||
|
```bash
|
||||||
|
# 需要创建 .NET 包装器项目
|
||||||
|
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 自动化脚本
|
||||||
|
|
||||||
|
### Enigma Virtual Box 自动化脚本
|
||||||
|
```powershell
|
||||||
|
# package_single_exe.ps1
|
||||||
|
$enigmaPath = "C:\Program Files\Enigma Virtual Box\enigmavb.exe"
|
||||||
|
$inputFile = "build\windows\x64\runner\Release\hostexecutor.exe"
|
||||||
|
$outputFile = "dist\HostExecutor_Single.exe"
|
||||||
|
$folderPath = "build\windows\x64\runner\Release"
|
||||||
|
|
||||||
|
& $enigmaPath /sf $inputFile /lf $outputFile /folder $folderPath /compress
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📦 打包后文件结构
|
||||||
|
|
||||||
|
### 单文件输出
|
||||||
|
```
|
||||||
|
dist/
|
||||||
|
└── HostExecutor_Single.exe # 单个可执行文件(50-100MB)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 文件大小分析
|
||||||
|
- **原始文件**: 约 30-50MB
|
||||||
|
- **压缩后**: 约 25-40MB(取决于压缩率)
|
||||||
|
- **最终大小**: 50-100MB(包含所有依赖)
|
||||||
|
|
||||||
|
## ⚠️ 注意事项
|
||||||
|
|
||||||
|
### 运行时依赖
|
||||||
|
1. **Windows 版本**: Windows 10 版本 1903+ 或 Windows 11
|
||||||
|
2. **系统组件**: 确保目标系统有最新的 Windows 更新
|
||||||
|
3. **防病毒软件**: 单文件可能被误报,需要添加信任
|
||||||
|
|
||||||
|
### 性能影响
|
||||||
|
- **启动时间**: 单文件启动会稍慢(需要解压)
|
||||||
|
- **内存使用**: 运行时内存占用相同
|
||||||
|
- **文件大小**: 比多文件版本大约 10-20%
|
||||||
|
|
||||||
|
## 🎯 推荐方案
|
||||||
|
|
||||||
|
### 开发阶段
|
||||||
|
使用多文件版本,便于调试和更新。
|
||||||
|
|
||||||
|
### 分发阶段
|
||||||
|
使用 Enigma Virtual Box 创建单文件版本:
|
||||||
|
1. **简单易用** - 图形化界面
|
||||||
|
2. **压缩率高** - 有效减小文件大小
|
||||||
|
3. **兼容性好** - 支持所有 Windows 版本
|
||||||
|
4. **免费** - 个人和商业使用都免费
|
||||||
|
|
||||||
|
## 📋 下一步行动
|
||||||
|
|
||||||
|
1. **安装 Enigma Virtual Box**
|
||||||
|
2. **测试单文件打包**
|
||||||
|
3. **验证运行效果**
|
||||||
|
4. **创建自动化打包流程**
|
||||||
|
|
||||||
|
## 🔗 相关资源
|
||||||
|
|
||||||
|
- [Enigma Virtual Box 官网](https://enigmaprotector.com/en/downloads.html)
|
||||||
|
- [Inno Setup 官网](https://jrsoftware.org/isinfo.php)
|
||||||
|
- [Flutter Windows 文档](https://docs.flutter.dev/desktop)
|
||||||
97
package_with_enigma.ps1
Normal file
97
package_with_enigma.ps1
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# Flutter Windows 单文件打包脚本 - Enigma Virtual Box
|
||||||
|
# 以管理员身份运行
|
||||||
|
|
||||||
|
Write-Host "=== Flutter Windows 单文件打包工具 ===" -ForegroundColor Green
|
||||||
|
|
||||||
|
# 配置参数
|
||||||
|
$projectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$buildPath = "$projectRoot\build\windows\x64\runner\Release"
|
||||||
|
$outputPath = "$projectRoot\dist"
|
||||||
|
$enigmaPath = "C:\Program Files\Enigma Virtual Box\enigmavb.exe"
|
||||||
|
|
||||||
|
# 检查构建文件
|
||||||
|
Write-Host "`n检查构建文件..." -ForegroundColor Yellow
|
||||||
|
if (-not (Test-Path $buildPath)) {
|
||||||
|
Write-Host "错误: 构建文件不存在,请先运行 flutter build windows" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
if (-not (Test-Path $outputPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $outputPath -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查 Enigma Virtual Box
|
||||||
|
if (-not (Test-Path $enigmaPath)) {
|
||||||
|
Write-Host "错误: Enigma Virtual Box 未安装" -ForegroundColor Red
|
||||||
|
Write-Host "请下载安装: https://enigmaprotector.com/en/downloads.html" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取主程序名称
|
||||||
|
$exeFile = Get-ChildItem -Path $buildPath -Filter "*.exe" | Select-Object -First 1
|
||||||
|
if (-not $exeFile) {
|
||||||
|
Write-Host "错误: 未找到可执行文件" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$inputExe = $exeFile.FullName
|
||||||
|
$outputExe = "$outputPath\$($exeFile.BaseName)_Single.exe"
|
||||||
|
|
||||||
|
Write-Host "主程序: $inputExe" -ForegroundColor Cyan
|
||||||
|
Write-Host "输出文件: $outputExe" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# 创建打包配置文件
|
||||||
|
$configContent = @"
|
||||||
|
; Enigma Virtual Box 配置文件
|
||||||
|
[Config]
|
||||||
|
InputFile=$inputExe
|
||||||
|
OutputFile=$outputExe
|
||||||
|
Files=%DEFAULT FOLDER%
|
||||||
|
VirtualizationMode=Never Write To Disk
|
||||||
|
Compression=Yes
|
||||||
|
ShareVirtualSystem=Yes
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
; 添加整个 Release 文件夹
|
||||||
|
Folder=$buildPath\*
|
||||||
|
"@
|
||||||
|
|
||||||
|
$configFile = "$outputPath\package_config.evb"
|
||||||
|
Set-Content -Path $configFile -Value $configContent
|
||||||
|
|
||||||
|
# 执行打包
|
||||||
|
Write-Host "`n开始打包..." -ForegroundColor Yellow
|
||||||
|
Write-Host "这可能需要几分钟时间,请耐心等待..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$process = Start-Process -FilePath $enigmaPath -ArgumentList "/sf", $inputExe, "/lf", $outputExe, "/folder", $buildPath, "/compress" -Wait -PassThru
|
||||||
|
|
||||||
|
if ($process.ExitCode -eq 0) {
|
||||||
|
Write-Host "`n✅ 打包成功!" -ForegroundColor Green
|
||||||
|
|
||||||
|
# 显示结果信息
|
||||||
|
$originalSize = (Get-Item $inputExe).Length / 1MB
|
||||||
|
$packedSize = (Get-Item $outputExe).Length / 1MB
|
||||||
|
$compressionRatio = [math]::Round((1 - $packedSize / $originalSize) * 100, 2)
|
||||||
|
|
||||||
|
Write-Host "`n打包结果:" -ForegroundColor Cyan
|
||||||
|
Write-Host "原始大小: $([math]::Round($originalSize, 2)) MB" -ForegroundColor White
|
||||||
|
Write-Host "打包大小: $([math]::Round($packedSize, 2)) MB" -ForegroundColor White
|
||||||
|
Write-Host "压缩率: $compressionRatio%" -ForegroundColor White
|
||||||
|
Write-Host "输出文件: $outputExe" -ForegroundColor White
|
||||||
|
|
||||||
|
Write-Host "`n📋 使用说明:" -ForegroundColor Yellow
|
||||||
|
Write-Host "1. 将生成的单文件复制到目标计算机" -ForegroundColor White
|
||||||
|
Write-Host "2. 直接运行即可,无需安装其他依赖" -ForegroundColor White
|
||||||
|
Write-Host "3. 首次运行可能需要管理员权限" -ForegroundColor White
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Write-Host "`n❌ 打包失败!" -ForegroundColor Red
|
||||||
|
Write-Host "错误代码: $($process.ExitCode)" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理临时文件
|
||||||
|
Remove-Item $configFile -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
Write-Host "`n按任意键退出..." -ForegroundColor Gray
|
||||||
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||||
140
说明文档.md
Normal file
140
说明文档.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
# Windows 构建项目说明文档
|
||||||
|
|
||||||
|
## 🎯 项目概述
|
||||||
|
|
||||||
|
本项目是一个 Flutter Windows 应用程序,已成功配置完整的 Windows 构建流程。
|
||||||
|
|
||||||
|
## ✅ 构建状态
|
||||||
|
|
||||||
|
**当前状态**: ✅ **构建成功**
|
||||||
|
|
||||||
|
- **Debug 构建**: ✓ 成功 (282.5s)
|
||||||
|
- **Release 构建**: ✓ 成功 (27s)
|
||||||
|
- **构建环境**: Windows Server + Visual Studio 2022 Enterprise
|
||||||
|
|
||||||
|
## 🏗️ 构建流程
|
||||||
|
|
||||||
|
### 1. 环境准备
|
||||||
|
- ✅ Flutter 3.24.5 已安装
|
||||||
|
- ✅ Visual Studio 2022 Enterprise 已配置
|
||||||
|
- ✅ NuGet 6.14.0 已安装(通过 Chocolatey)
|
||||||
|
- ✅ Windows 长路径支持已启用
|
||||||
|
|
||||||
|
### 2. 构建步骤
|
||||||
|
1. **代码检出** - 从 Gitea 仓库获取代码
|
||||||
|
2. **依赖安装** - 安装 Flutter 依赖包
|
||||||
|
3. **代码生成** - 运行 build_runner 生成代码
|
||||||
|
4. **Windows 构建** - 构建 Debug 和 Release 版本
|
||||||
|
5. **产物上传** - 上传构建产物到 Gitea Actions
|
||||||
|
|
||||||
|
### 3. 构建输出
|
||||||
|
```
|
||||||
|
Debug: build/windows/x64/runner/Debug/hostexecutor.exe
|
||||||
|
Release: build/windows/x64/runner/Release/hostexecutor.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 关键修复记录
|
||||||
|
|
||||||
|
### 1. NuGet 安装问题
|
||||||
|
**问题**: SSL/TLS 安全通道错误
|
||||||
|
**解决方案**:
|
||||||
|
- 使用 Chocolatey 安装 NuGet
|
||||||
|
- 命令: `choco install nuget.commandline -y`
|
||||||
|
|
||||||
|
### 2. Flutter 路径配置
|
||||||
|
**问题**: Flutter 命令未找到
|
||||||
|
**解决方案**:
|
||||||
|
- 添加 Flutter 到 PATH: `C:\flutter\bin`
|
||||||
|
- 在每个构建步骤中显式设置 PATH
|
||||||
|
|
||||||
|
### 3. 长路径问题
|
||||||
|
**问题**: Windows 路径长度限制
|
||||||
|
**解决方案**:
|
||||||
|
- 启用 Windows 长路径支持
|
||||||
|
- 注册表设置: `LongPathsEnabled = 1`
|
||||||
|
|
||||||
|
### 4. 构建产物路径
|
||||||
|
**问题**: 上传路径配置错误
|
||||||
|
**解决方案**:
|
||||||
|
- 修正路径: `build/windows/x64/runner/Debug/`
|
||||||
|
- 原错误路径: `build/windows/runner/Debug/`
|
||||||
|
|
||||||
|
## 📁 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
/Users/Apple/vpn/hi-client/
|
||||||
|
├── .gitea/workflows/ # Gitea Actions 工作流配置
|
||||||
|
├── lib/ # Flutter 源代码
|
||||||
|
│ ├── app/ # 应用程序代码
|
||||||
|
│ ├── core/ # 核心功能
|
||||||
|
│ └── singbox/ # SingBox 相关
|
||||||
|
├── windows/ # Windows 平台配置
|
||||||
|
├── libcore/ # 核心库(子模块)
|
||||||
|
└── build/ # 构建输出(运行时生成)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 本地构建
|
||||||
|
```bash
|
||||||
|
# 安装 Flutter 依赖
|
||||||
|
flutter pub get
|
||||||
|
|
||||||
|
# 生成代码
|
||||||
|
dart run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
|
# 构建 Windows Debug
|
||||||
|
flutter build windows
|
||||||
|
|
||||||
|
# 构建 Windows Release
|
||||||
|
flutter build windows --release
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用脚本
|
||||||
|
```bash
|
||||||
|
# 运行 Windows 构建修复脚本
|
||||||
|
./fix_windows_build.ps1
|
||||||
|
|
||||||
|
# 安装 NuGet(如果需要)
|
||||||
|
./install_nuget_simple.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 注意事项
|
||||||
|
|
||||||
|
### 1. 构建环境要求
|
||||||
|
- Windows 10/11 或 Windows Server
|
||||||
|
- Visual Studio 2022(包含 C++ 开发工具)
|
||||||
|
- Flutter 3.24.5+
|
||||||
|
- NuGet CLI
|
||||||
|
|
||||||
|
### 2. 常见问题
|
||||||
|
- **CMake 警告**: 可忽略,不影响构建
|
||||||
|
- **WebView2 警告**: 类型转换警告,不影响功能
|
||||||
|
- **路径问题**: 确保使用正确的 x64 路径
|
||||||
|
|
||||||
|
### 3. 性能优化
|
||||||
|
- Debug 构建约 4.7 分钟
|
||||||
|
- Release 构建约 27 秒
|
||||||
|
- 建议使用 Release 版本进行分发
|
||||||
|
|
||||||
|
## 🔍 调试工具
|
||||||
|
|
||||||
|
### 构建日志分析
|
||||||
|
查看 `构建日志分析.md` 文件获取详细的构建日志分析和故障排除指南。
|
||||||
|
|
||||||
|
### 连接状态调试
|
||||||
|
使用 `debug_connection_status.dart` 工具检查应用连接状态。
|
||||||
|
|
||||||
|
## 📞 支持
|
||||||
|
|
||||||
|
如遇到构建问题,请检查:
|
||||||
|
1. 环境配置是否正确
|
||||||
|
2. 依赖是否完整安装
|
||||||
|
3. 查看构建日志获取具体错误信息
|
||||||
|
4. 参考本说明文档的修复记录
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**最后更新**: $(date)
|
||||||
|
**构建状态**: ✅ 成功
|
||||||
|
**文档版本**: 1.0
|
||||||
Loading…
x
Reference in New Issue
Block a user