#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." }