# get-vnc.ps1 # Downloads a portable VNC server (UltraVNC) for Windows and places its # files into a local "vnc" folder so web-vnc can auto-launch it with --spawn. # # Usage (from repo root): .\scripts\get-vnc.ps1 # Override the download URL(s): .\scripts\get-vnc.ps1 -Url "https://.../UltraVNC_x64.zip" # # If all download attempts fail, the script opens https://uvnc.com/downloads.html # in your browser — download the UltraVNC .zip (NOT the installer), extract it and # copy winvnc.exe together with its companion .dll/.dsm files into the project's # "vnc" folder, then run `run.bat`. [CmdletBinding()] param( [string[]]$Url = @( "https://downloads.sourceforge.net/project/ultravnc/UltraVNC%201.4.3.0%20bin/UltraVNC_1.4.3.0_x64.zip", "https://downloads.sourceforge.net/project/ultravnc/UltraVNC_1.4.3.0/UltraVNC_1.4.3.0_x64.zip", "https://sourceforge.net/projects/ultravnc/files/UltraVNC%201.4.3.0%20bin/UltraVNC_1.4.3.0_x64.zip/download" ) ) $ErrorActionPreference = "Stop" $repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..") $vncDir = Join-Path $repoRoot "vnc" New-Item -ItemType Directory -Force -Path $vncDir | Out-Null $work = Join-Path $env:TEMP ("webvnc-vnc-" + [guid]::NewGuid()) New-Item -ItemType Directory -Force -Path $work | Out-Null function Test-Zip([string]$path) { if (-not (Test-Path $path)) { return $false } $fs = [System.IO.File]::OpenRead($path) try { $b = New-Object byte[] 4 $n = $fs.Read($b, 0, 4) return ($n -ge 2 -and $b[0] -eq 0x50 -and $b[1] -eq 0x4B) # "PK" } finally { $fs.Close() } } function Get-Zip { param([string[]]$urls) $ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 web-vnc-installer" foreach ($u in $urls) { $archive = Join-Path $work "vnc.zip" Remove-Item $archive -ErrorAction SilentlyContinue Write-Host "" Write-Host "Trying: $u" foreach ($attempt in 1..2) { try { Invoke-WebRequest -Uri $u -OutFile $archive -UseBasicParsing -TimeoutSec 300 -UserAgent $ua -MaximumRedirection 20 if (Test-Zip $archive) { $len = [Math]::Round((Get-Item $archive).Length / 1MB, 1) Write-Host " downloaded zip (${len} MB)" return $archive } Write-Host " response was not a zip (HTML page?), retrying ..." Remove-Item $archive -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 } catch { Write-Host " attempt ${attempt} failed: $($_.Exception.Message)" Start-Sleep -Seconds 2 } } } return $null } function Manual-Fallback { $page = "https://uvnc.com/downloads.html" Write-Host "" Write-Host "============================================================" -ForegroundColor Yellow Write-Host "Automatic download failed. Opening the UltraVNC download page." -ForegroundColor Yellow Write-Host "============================================================" -ForegroundColor Yellow try { Start-Process $page } catch { Write-Host "Open manually: $page" } Write-Host "" Write-Host "Manual steps:" Write-Host " 1. On the page, download the UltraVNC .zip archive (the portable" Write-Host " package, NOT the installer)." Write-Host " 2. Extract it." Write-Host " 3. Copy winvnc.exe AND its companion .dll/.dsm files (everything" Write-Host " from the extracted folder) into this folder:" Write-Host " $vncDir" Write-Host " 4. Run: .\run.bat" Write-Host "" } try { $archive = Get-Zip -urls $Url if (-not $archive) { Manual-Fallback; exit 1 } Write-Host "Extracting ..." Expand-Archive -Path $archive -DestinationPath $work -Force $server = Get-ChildItem -Recurse -Path $work -Filter "winvnc.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $server) { $server = Get-ChildItem -Recurse -Path $work -Filter "tvnserver.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 } if (-not $server) { Write-Host "winvnc.exe not found in the archive." -ForegroundColor Yellow Manual-Fallback exit 1 } $srcDir = $server.DirectoryName Write-Host "Found VNC server in: $srcDir" Write-Host "Copying files into: $vncDir" Copy-Item -Path (Join-Path $srcDir "*") -Destination $vncDir -Recurse -Force Write-Host "" Write-Host "Done. Installed: $(Join-Path $vncDir $server.Name)" -ForegroundColor Green Write-Host "Now run: .\run.bat" } finally { Remove-Item -Path $work -Recurse -Force -ErrorAction SilentlyContinue }