添加install_build_tools.bat用于自动安装构建工具 添加package_windows_single_exe.ps1用于打包Flutter应用为单文件 改进inno_setup.sas增加卸载清理逻辑和进程终止功能
168 lines
5.5 KiB
PowerShell
168 lines
5.5 KiB
PowerShell
#Requires -RunAsAdministrator
|
|
<#
|
|
.SYNOPSIS
|
|
Builds and packages a Flutter Windows application into a single executable.
|
|
|
|
.DESCRIPTION
|
|
This script automates the entire process of creating a single-file executable for a Flutter Windows project.
|
|
It performs the following steps:
|
|
1. Checks for and installs Chocolatey if not present.
|
|
2. Installs Enigma Virtual Box and 7-Zip using Chocolatey.
|
|
3. Builds the Flutter application in release mode.
|
|
4. Packages the build output into a single EXE using Enigma Virtual Box.
|
|
5. If Enigma fails, it falls back to creating a 7-Zip self-extracting archive.
|
|
6. Places the final packaged executable in the 'dist' directory.
|
|
|
|
.NOTES
|
|
- This script must be run with Administrator privileges to install software.
|
|
- An internet connection is required for the first run to download and install dependencies.
|
|
#>
|
|
|
|
# --- Configuration ---
|
|
$ErrorActionPreference = "Stop"
|
|
$buildPath = ".\build\windows\x64\runner\Release"
|
|
$outputPath = ".\dist"
|
|
|
|
# --- Helper Functions ---
|
|
function Test-CommandExists {
|
|
param($command)
|
|
return (Get-Command $command -ErrorAction SilentlyContinue)
|
|
}
|
|
|
|
function Install-Chocolatey {
|
|
if (Test-CommandExists "choco") {
|
|
Write-Host "✅ Chocolatey is already installed."
|
|
return
|
|
}
|
|
|
|
Write-Host "Chocolatey not found. Installing..."
|
|
try {
|
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
|
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
|
Write-Host "✅ Chocolatey installed successfully."
|
|
} catch {
|
|
Write-Host "❌ Failed to install Chocolatey. Please install it manually and re-run the script."
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
function Install-Tools {
|
|
Write-Host "Checking for required tools (Enigma Virtual Box, 7-Zip)..."
|
|
$tools = @("enigma-virtual-box", "7zip")
|
|
foreach ($tool in $tools) {
|
|
if (choco list --local-only --exact $tool) {
|
|
Write-Host "✅ $tool is already installed."
|
|
} else {
|
|
Write-Host "Installing $tool..."
|
|
try {
|
|
choco install $tool -y --force
|
|
Write-Host "✅ $tool installed successfully."
|
|
} catch {
|
|
Write-Host "❌ Failed to install $tool."
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# --- Main Script ---
|
|
|
|
# 1. Setup Environment
|
|
Write-Host "=== 1/4: Setting up build environment ==="
|
|
Install-Chocolatey
|
|
Install-Tools
|
|
|
|
# 2. Build Flutter App
|
|
Write-Host "=== 2/4: Building Flutter Windows application (Release) ==="
|
|
try {
|
|
flutter build windows --release
|
|
} catch {
|
|
Write-Host "❌ Flutter build failed."
|
|
exit 1
|
|
}
|
|
|
|
# 3. Package Application
|
|
Write-Host "=== 3/4: Packaging into a single executable ==="
|
|
if (-not (Test-Path $buildPath)) {
|
|
Write-Host "❌ Build directory not found: $buildPath"
|
|
exit 1
|
|
}
|
|
|
|
# Create output directory
|
|
New-Item -ItemType Directory -Path $outputPath -Force | Out-Null
|
|
|
|
# Get main executable
|
|
$exeFile = Get-ChildItem -Path $buildPath -Filter "*.exe" | Select-Object -First 1
|
|
if (-not $exeFile) {
|
|
Write-Host "❌ No executable found in build directory."
|
|
exit 1
|
|
}
|
|
|
|
$inputExe = $exeFile.FullName
|
|
$outputExe = "$outputPath\$($exeFile.BaseName)_Single.exe"
|
|
$enigmaCliPath = "C:\Program Files\Enigma Virtual Box\enigmavb.exe"
|
|
$packageSuccess = $false
|
|
|
|
# Attempt to package with Enigma Virtual Box
|
|
if (Test-Path $enigmaCliPath) {
|
|
Write-Host "Attempting to package with Enigma Virtual Box..."
|
|
try {
|
|
& $enigmaCliPath /quiet /project "$outputPath\project.evb" /input "$inputExe" /output "$outputExe" /folder "$buildPath" /compress 3 /deleteext
|
|
|
|
if ($?) {
|
|
Write-Host "✅ Enigma Virtual Box packaging successful."
|
|
$packageSuccess = $true
|
|
} else {
|
|
Write-Host "⚠️ Enigma Virtual Box packaging failed. Exit code: $lastexitcode"
|
|
}
|
|
} catch {
|
|
Write-Host "⚠️ An error occurred during Enigma Virtual Box packaging."
|
|
}
|
|
} else {
|
|
Write-Host "⚠️ Enigma Virtual Box not found at $enigmaCliPath."
|
|
}
|
|
|
|
# 4. Fallback to 7-Zip if Enigma failed
|
|
if (-not $packageSuccess) {
|
|
Write-Host "=== 4/4: Fallback: Packaging with 7-Zip SFX ==="
|
|
$7zipCliPath = "C:\Program Files\7-Zip\7z.exe"
|
|
$outputSfx = "$outputPath\$($exeFile.BaseName)_Package.exe"
|
|
|
|
if (-not (Test-Path $7zipCliPath)) {
|
|
Write-Host "❌ 7-Zip not found. Cannot create self-extracting archive."
|
|
exit 1
|
|
}
|
|
|
|
$sfxConfig = @'
|
|
;!@Install@!UTF-8!
|
|
Title="Flutter Application"
|
|
BeginPrompt="Do you want to extract and run the application?"
|
|
RunProgram="%%T\%%S\$($exeFile.Name)"
|
|
;!@InstallEnd@!
|
|
'@
|
|
$sfxConfigFile = "$outputPath\sfx_config.txt"
|
|
Set-Content -Path $sfxConfigFile -Value $sfxConfig
|
|
|
|
try {
|
|
& $7zipCliPath a -sfx7z.sfx "$outputSfx" "$buildPath\*" -r "-i!$sfxConfigFile"
|
|
Write-Host "✅ 7-Zip self-extracting archive created successfully."
|
|
$outputExe = $outputSfx
|
|
$packageSuccess = $true
|
|
} catch {
|
|
Write-Host "❌ 7-Zip packaging failed."
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# --- Final Summary ---
|
|
if ($packageSuccess) {
|
|
$finalSize = (Get-Item $outputExe).Length / 1MB
|
|
Write-Host "================================================"
|
|
Write-Host "✅ Packaging Complete!"
|
|
Write-Host " Output file: $outputExe"
|
|
Write-Host " Size: $([math]::Round($finalSize, 2)) MB"
|
|
Write-Host "================================================"
|
|
} else {
|
|
Write-Host "❌ All packaging attempts failed."
|
|
} |