Files
sm-emby-share/scripts/prepare-fvp-windows-deps.ps1
T

220 lines
7.5 KiB
PowerShell
Raw Normal View History

2026-07-14 11:11:36 +08:00
[CmdletBinding()]
param(
[string]$Url = '',
[switch]$ForceRefresh
)
$ErrorActionPreference = 'Stop'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$MdkVersion = '0.37.0'
function Test-SevenZipArchive {
param([string]$Path)
if (-not (Test-Path $Path)) { return $false }
$stream = [System.IO.File]::OpenRead($Path)
try {
if ($stream.Length -lt 6) { return $false }
$buffer = New-Object byte[] 6
[void]$stream.Read($buffer, 0, 6)
} finally {
$stream.Dispose()
}
$magic = 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C
for ($i = 0; $i -lt 6; $i++) {
if ($buffer[$i] -ne $magic[$i]) { return $false }
}
return $true
}
function Resolve-CMakeExecutable {
$pathCommand = Get-Command 'cmake.exe' -ErrorAction SilentlyContinue
if ($pathCommand) {
return $pathCommand.Source
}
$visualStudioInstallations = @()
$vswherePath = Join-Path ${Env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
if (Test-Path $vswherePath) {
$visualStudioInstallations += @(
& $vswherePath -products '*' -property installationPath 2>$null
)
}
foreach ($programFilesRoot in @($Env:ProgramFiles, ${Env:ProgramFiles(x86)})) {
if (-not $programFilesRoot) { continue }
foreach ($edition in @('BuildTools', 'Community', 'Professional', 'Enterprise')) {
$visualStudioInstallations += Join-Path $programFilesRoot "Microsoft Visual Studio\2022\$edition"
}
}
foreach ($installationPath in $visualStudioInstallations | Select-Object -Unique) {
if (-not $installationPath) { continue }
$candidate = Join-Path $installationPath 'Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe'
if (Test-Path $candidate) {
return $candidate
}
}
$androidSdkRoots = @(
$Env:ANDROID_SDK_ROOT,
$Env:ANDROID_HOME,
$(if ($Env:LOCALAPPDATA) { Join-Path $Env:LOCALAPPDATA 'Android\sdk' })
) | Where-Object { $_ -and (Test-Path $_) } | Select-Object -Unique
foreach ($androidSdkRoot in $androidSdkRoots) {
$cmakeRoot = Join-Path $androidSdkRoot 'cmake'
if (-not (Test-Path $cmakeRoot)) { continue }
$candidate = Get-ChildItem $cmakeRoot -Directory -ErrorAction SilentlyContinue |
Sort-Object Name -Descending |
ForEach-Object { Join-Path $_.FullName 'bin\cmake.exe' } |
Where-Object { Test-Path $_ } |
Select-Object -First 1
if ($candidate) {
return $candidate
}
}
return $null
}
$ProjectRoot = Split-Path -Parent $PSScriptRoot
Set-Location $ProjectRoot
$PackageConfig = Join-Path $ProjectRoot '.dart_tool\package_config.json'
if (-not (Test-Path $PackageConfig)) {
throw "package_config.json not found: $PackageConfig (run flutter pub get first)"
}
$config = Get-Content $PackageConfig -Raw | ConvertFrom-Json
$fvp = $config.packages | Where-Object { $_.name -eq 'fvp' } | Select-Object -First 1
if (-not $fvp) {
throw 'Package fvp not found in .dart_tool/package_config.json'
}
$fvpRoot = [Uri]$fvp.rootUri
if (-not $fvpRoot.IsFile) {
throw "Unsupported fvp rootUri: $($fvp.rootUri)"
}
$fvpWindowsDir = Join-Path $fvpRoot.LocalPath 'windows'
if (-not (Test-Path $fvpWindowsDir)) {
throw "fvp windows directory not found: $fvpWindowsDir"
}
$sdkDir = Join-Path $fvpWindowsDir 'mdk-sdk'
$sdkVersionMarkerPath = Join-Path $sdkDir '.smplayer-mdk-version'
$archivePath = Join-Path $fvpWindowsDir "mdk-sdk-windows-x64-v$MdkVersion-vs2026.7z"
if ($ForceRefresh) {
Write-Host "==> Force refreshing fvp mdk-sdk v$MdkVersion" -ForegroundColor Yellow
if (Test-Path $sdkDir) {
Remove-Item $sdkDir -Recurse -Force
}
if (Test-Path $archivePath) {
Remove-Item $archivePath -Force
}
}
if (Test-Path $sdkDir) {
$installedMdkVersion = if (Test-Path $sdkVersionMarkerPath) {
(Get-Content $sdkVersionMarkerPath -Raw).Trim()
} else {
''
}
if ($installedMdkVersion -eq $MdkVersion) {
Write-Host "==> fvp mdk-sdk v$MdkVersion already exists: $sdkDir" -ForegroundColor Green
exit 0
}
$displayVersion = if ($installedMdkVersion) { $installedMdkVersion } else { 'unknown' }
Write-Host "==> Replacing cached mdk-sdk v$displayVersion with v$MdkVersion" -ForegroundColor Yellow
Remove-Item $sdkDir -Recurse -Force
}
$candidates = @()
if ($Url) {
$candidates += $Url
} else {
$candidates += "https://github.com/wang-bin/mdk-sdk/releases/download/v$MdkVersion/mdk-sdk-windows-x64-vs2026.7z"
}
if ((Test-Path $archivePath) -and -not (Test-SevenZipArchive $archivePath)) {
Write-Host "==> Cached archive is not a valid 7z, removing: $archivePath" -ForegroundColor Yellow
Remove-Item $archivePath -Force
}
if (-not (Test-Path $archivePath)) {
$downloaded = $false
:outer foreach ($candidate in $candidates) {
$maxAttempts = 3
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
Write-Host "==> Downloading mdk-sdk (attempt $attempt/$maxAttempts): $candidate" -ForegroundColor Cyan
try {
Invoke-WebRequest -Uri $candidate -OutFile $archivePath `
-UseBasicParsing -MaximumRedirection 10 `
-UserAgent 'Mozilla/5.0' -TimeoutSec 120
} catch {
Write-Host " download failed: $($_.Exception.Message)" -ForegroundColor Yellow
if (Test-Path $archivePath) { Remove-Item $archivePath -Force }
if ($attempt -lt $maxAttempts) {
$delay = $attempt * 10
Write-Host " retrying in ${delay}s..." -ForegroundColor Yellow
Start-Sleep -Seconds $delay
}
continue
}
if (Test-SevenZipArchive $archivePath) {
$downloaded = $true
break outer
}
$size = (Get-Item $archivePath).Length
Write-Host " not a valid 7z archive (size=$size bytes), trying next" -ForegroundColor Yellow
Remove-Item $archivePath -Force
break # bad content, skip retries for this URL
}
}
if (-not $downloaded) {
throw "Failed to download a valid mdk-sdk archive from: $($candidates -join ', ')"
}
}
Write-Host "==> Extracting mdk-sdk to: $fvpWindowsDir" -ForegroundColor Cyan
$sevenZipCommand = Get-Command '7z.exe' -ErrorAction SilentlyContinue
$sevenZip = if ($sevenZipCommand) {
$sevenZipCommand.Source
} else {
@(
"$Env:ProgramFiles\7-Zip\7z.exe",
"${Env:ProgramFiles(x86)}\7-Zip\7z.exe"
) | Where-Object { Test-Path $_ } | Select-Object -First 1
}
if ($sevenZip) {
& $sevenZip x '-y' "-o$fvpWindowsDir" $archivePath
} else {
$cmakeExecutable = Resolve-CMakeExecutable
if (-not $cmakeExecutable) {
throw 'Neither 7-Zip nor CMake was found. Install the Visual Studio C++ CMake tools or 7-Zip, then retry.'
}
Write-Host "==> Using CMake: $cmakeExecutable" -ForegroundColor DarkGray
Push-Location $fvpWindowsDir
try {
& $cmakeExecutable -E tar xvf $archivePath
} finally {
Pop-Location
}
}
if ($LASTEXITCODE -ne 0) {
throw "Failed to extract mdk-sdk (exit $LASTEXITCODE)"
}
if (-not (Test-Path $sdkDir)) {
throw "mdk-sdk not found after extraction: $sdkDir"
}
Set-Content -Path $sdkVersionMarkerPath -Value $MdkVersion -NoNewline
Write-Host "==> fvp mdk-sdk v$MdkVersion ready: $sdkDir" -ForegroundColor Green