[CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [ValidatePattern('^\d+\.\d+\.\d+$')] [string]$Version, [switch]$Force ) $ErrorActionPreference = 'Stop' $releasesDir = Join-Path $PSScriptRoot '..\Releases' | Resolve-Path $packagePattern = "*-{0}-full.nupkg" -f $Version $packages = @(Get-ChildItem -LiteralPath $releasesDir -Filter $packagePattern -File) if ($packages.Count -eq 0) { throw "Full package not found for version $Version`: $releasesDir\$packagePattern" } if ($packages.Count -gt 1) { throw "Multiple full packages found for version $Version`: $($packages.FullName -join ', ')" } $vpk = Get-Command vpk -ErrorAction SilentlyContinue if (-not $vpk) { throw 'vpk was not found. Install it with: dotnet tool install -g vpk' } $outputDir = Join-Path $releasesDir "MSI\$Version" $tempDir = Join-Path ([IO.Path]::GetTempPath()) ("xploreplane-msi-" + [Guid]::NewGuid().ToString('N')) $targetMsi = Join-Path $outputDir "XplorePlane-$Version-win.msi" try { New-Item -ItemType Directory -Path $tempDir -Force | Out-Null New-Item -ItemType Directory -Path $outputDir -Force | Out-Null if ((Test-Path -LiteralPath $targetMsi) -and -not $Force) { throw "Target MSI already exists: $targetMsi. Use -Force to overwrite it." } Write-Host "Extracting: $($packages[0].Name)" Add-Type -AssemblyName System.IO.Compression.FileSystem [IO.Compression.ZipFile]::ExtractToDirectory($packages[0].FullName, $tempDir) $packDir = Join-Path $tempDir 'lib\app' if (-not (Test-Path -LiteralPath (Join-Path $packDir 'XplorePlane.exe'))) { throw "The package does not contain the application directory or main executable: $packDir" } Write-Host "Generating MSI in: $outputDir" & $vpk.Source pack ` --packId Hexagon.XplorePlane ` --packTitle XplorePlane ` --packAuthors Hexagon ` --packVersion $Version ` --packDir $packDir ` --mainExe XplorePlane.exe ` --msi ` --msiVersion $Version ` --instLocation Either ` --outputDir $outputDir if ($LASTEXITCODE -ne 0) { throw "vpk pack failed with exit code: $LASTEXITCODE" } $generatedMsi = @(Get-ChildItem -LiteralPath $outputDir -Filter '*.msi' -File) if ($generatedMsi.Count -ne 1) { throw "Expected one MSI, found $($generatedMsi.Count)." } if ($generatedMsi[0].FullName -ne $targetMsi) { Move-Item -LiteralPath $generatedMsi[0].FullName -Destination $targetMsi -Force:$Force } Write-Host "Completed: $targetMsi" -ForegroundColor Green } finally { if (Test-Path -LiteralPath $tempDir) { Remove-Item -LiteralPath $tempDir -Recurse -Force } }