# build-windows.ps1 # # Build RustDesk 1.4.7 (our fork) on Windows 11. # Run from an "x64 Native Tools Command Prompt for VS 2022" PowerShell window. # # What it does: # 1. flutter pub get # 2. flutter_rust_bridge_codegen (regenerates generated_bridge.dart) # — REMEMBER: hand-patch the 3 sites in generated_bridge.dart! # 3. cargo build --release # 4. flutter build windows --release # 5. Optional: signtool sign the .exe # 6. Zip up the Release/ folder # # Re-run this script any time: incremental builds are fast (~30 sec for # Flutter, ~1 min for Rust when nothing changed). $ErrorActionPreference = "Stop" Set-StrictMode -Version Latest function Write-Section { param($msg) Write-Host "`n=== $msg ===" -ForegroundColor Cyan } function Write-Ok { param($msg) Write-Host " [OK] $msg" -ForegroundColor Green } function Write-Warn { param($msg) Write-Host " [WARN] $msg" -ForegroundColor Yellow } function Write-Err { param($msg) Write-Host " [ERR] $msg" -ForegroundColor Red } # ------- Config ------- $PROJECT_ROOT = "C:\prj\rustdesk" $VERSION = if ($env:VERSION) { $env:VERSION } else { "1.4.7" } $ARCH = "x86_64" # Should we sign? Set $env:SKIP_SIGN=1 to skip. $SKIP_SIGN = if ($env:SKIP_SIGN) { $env:SKIP_SIGN -eq "1" } else { $true } # Certificate path. Set $env:CERT_PATH to a .pfx file to sign. $CERT_PATH = $env:CERT_PATH $CERT_PASSWORD = $env:CERT_PASSWORD Push-Location $PROJECT_ROOT # ------- 1. flutter pub get ------- Write-Section "1/6 flutter pub get" & "$env:FLUTTER_ROOT\bin\flutter.bat" pub get Write-Ok "deps ready" # ------- 2. flutter_rust_bridge_codegen ------- Write-Section "2/6 flutter_rust_bridge_codegen (Flutter <-> Rust FFI bindings)" & "$env:USERPROFILE\.cargo\bin\flutter_rust_bridge_codegen.exe" ` --rust-input ./src/flutter_ffi.rs ` --dart-output ./flutter/lib/generated_bridge.dart ` --c-output ./flutter/windows/runner/bridge_generated.h Write-Ok "FFI bindings regenerated" Write-Host "" Write-Host " >>> REMINDER: re-apply the 3 hand-patches to flutter/lib/generated_bridge.dart <<<" -ForegroundColor Yellow Write-Host " 1. api2wire_int_32_list: asTypedList(raw.length).setAll(0, raw)" Write-Host " -> .cast().asTypedList(raw.length).setAll(0, raw)" Write-Host " 2. api2wire_uint_8_list: asTypedList(raw.length).setAll(0, raw)" Write-Host " -> .cast().asTypedList(raw.length).setAll(0, raw)" Write-Host " 3. typedef DartPort = ffi.Int; -> typedef DartPort = ffi.Int64;" Write-Host "" Write-Host " (These get regenerated every codegen run. The upstream Rust code" Write-Host " still has the old API; we patch after each generation.)" Write-Host "" # ------- 3. Rust build ------- Write-Section "3/6 cargo build --release --features flutter" & cargo build --release --features flutter Write-Ok "Rust build OK" # ------- 4. Flutter Windows build ------- Write-Section "4/6 flutter build windows --release" Push-Location flutter & "$env:FLUTTER_ROOT\bin\flutter.bat" build windows --release Pop-Location Write-Ok "Flutter build OK" # ------- 5. (Optional) sign with signtool ------- Write-Section "5/6 sign RustDesk.exe (optional)" $exePath = "flutter\build\windows\x64\runner\Release\RustDesk.exe" if ($SKIP_SIGN -or -not $CERT_PATH) { if (-not $CERT_PATH) { Write-Warn "No CERT_PATH set; skipping signing (unsigned binary)." } else { Write-Warn "SKIP_SIGN=1; skipping signing." } } elseif (-not (Test-Path $CERT_PATH)) { Write-Err "CERT_PATH=$CERT_PATH does not exist. Aborting." exit 1 } else { Write-Host " Signing $exePath with $CERT_PATH..." & signtool sign /f "$CERT_PATH" /p "$CERT_PASSWORD" /t http://timestamp.digicert.com "$exePath" if ($LASTEXITCODE -ne 0) { Write-Err "signtool failed with exit $LASTEXITCODE" exit 1 } Write-Ok "Signed" & signtool verify /pa "$exePath" | Out-Null if ($LASTEXITCODE -ne 0) { Write-Warn "Signature verification failed; binary still works (SmartScreen will warn on first launch)" } else { Write-Ok "Signature verified" } } # ------- 6. Zip up ------- Write-Section "6/6 Zip the Release folder" $releaseDir = "flutter\build\windows\x64\runner\Release" $zipPath = "rustdesk-$VERSION-$ARCH.zip" if (Test-Path $zipPath) { Remove-Item $zipPath -Force } Compress-Archive -Path "$releaseDir\*" -DestinationPath $zipPath -CompressionLevel Optimal $size = "{0:N1} MB" -f ((Get-Item $zipPath).Length / 1MB) Write-Ok "Created: $zipPath ($size)" Pop-Location Write-Section "Build complete" Write-Host "Output:" Write-Host " Build: $PROJECT_ROOT\flutter\build\windows\x64\runner\Release\" Write-Host " Zip: $PROJECT_ROOT\rustdesk-$VERSION-$ARCH.zip" Write-Host "" Write-Host "Distribution:" Write-Host " 1. Share rustdesk-$VERSION-$ARCH.zip with your users" Write-Host " 2. Each user unzips and double-clicks RustDesk.exe" Write-Host " 3. First launch: Windows SmartScreen will warn ('more info' -> 'run anyway')" Write-Host " 4. Or: sign the .exe with a real code-signing cert (no SmartScreen warning)" Write-Host "" Write-Host "Configure on the Win host:" Write-Host " ID Server: 114.55.133.123:21116" Write-Host " Relay: 114.55.133.123:21117" Write-Host " API: http://114.55.133.123:21118" Write-Host " Key: EXdBNGKAMYAKCzLGp0+5NnFIv9MCs1WfBYy1tFBKS78="