#Requires -Version 5.1 <# .SYNOPSIS Pack Navis.exe into an MSIX for Microsoft Store / sideload. .DESCRIPTION Builds Store assets, stages AppxManifest + Navis.exe, runs MakeAppx. Prefers MSIX over PWA: Navis needs Win32/WebView2 VPN and system-proxy access. .EXAMPLE .\scripts\pack-msix.ps1 .\scripts\pack-msix.ps1 -Version 3.9.0.1 -Publisher "CN=EvilFox" #> [CmdletBinding()] param( [string]$ExePath = "", [string]$OutDir = "", [string]$Version = "3.9.0.1", [string]$Name = "EvilFox.Navis", [string]$Publisher = "CN=EvilFox", [string]$DisplayName = "Navis", [string]$PublisherDisplayName = "EvilFox", [string]$CertPath = "", [string]$CertPassword = "", [switch]$SkipAssets ) $ErrorActionPreference = "Stop" $Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) Set-Location $Root if (-not $ExePath) { $ExePath = Join-Path $Root "dist\navis-release\windows\Navis.exe" } if (-not $OutDir) { $OutDir = Join-Path $Root "dist\navis-release\windows" } if (-not (Test-Path -LiteralPath $ExePath)) { throw "Navis.exe not found at '$ExePath'. Run build.bat first." } function Find-SdkTool([string]$name) { $candidates = @() $kits = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\bin" if (Test-Path $kits) { Get-ChildItem -Path $kits -Directory -ErrorAction SilentlyContinue | Sort-Object Name -Descending | ForEach-Object { $candidates += (Join-Path $_.FullName "x64\$name") $candidates += (Join-Path $_.FullName "x86\$name") } } foreach ($p in $candidates) { if (Test-Path -LiteralPath $p) { return $p } } $cmd = Get-Command $name -ErrorAction SilentlyContinue if ($cmd) { return $cmd.Source } return $null } $MakeAppx = Find-SdkTool "makeappx.exe" if (-not $SkipAssets) { Write-Host "Generating Store assets..." go run ./tools/mkstoreassets if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } } $Staging = Join-Path $Root "packaging\msix\_staging" if (Test-Path $Staging) { Remove-Item -Recurse -Force $Staging } New-Item -ItemType Directory -Path $Staging | Out-Null New-Item -ItemType Directory -Path (Join-Path $Staging "Assets") | Out-Null $AssetsSrc = Join-Path $Root "packaging\msix\Assets" Copy-Item -Path (Join-Path $AssetsSrc "*") -Destination (Join-Path $Staging "Assets") -Force Copy-Item -LiteralPath $ExePath -Destination (Join-Path $Staging "Navis.exe") -Force $ManifestSrc = Join-Path $Root "packaging\msix\AppxManifest.xml" $ManifestDst = Join-Path $Staging "AppxManifest.xml" $manifestText = Get-Content -LiteralPath $ManifestSrc -Raw -Encoding UTF8 # Prefer exact placeholder swaps so we never touch . $manifestText = $manifestText.Replace('Name="EvilFox.Navis"', "Name=`"$Name`"") $manifestText = $manifestText.Replace('Publisher="CN=EvilFox"', "Publisher=`"$Publisher`"") $manifestText = $manifestText.Replace('Version="3.9.0.1"', "Version=`"$Version`"") $manifestText = $manifestText.Replace('Navis', "$DisplayName") $manifestText = $manifestText.Replace('EvilFox', "$PublisherDisplayName") $manifestText = $manifestText.Replace('DisplayName="Navis"', "DisplayName=`"$DisplayName`"") [System.IO.File]::WriteAllText($ManifestDst, $manifestText, (New-Object System.Text.UTF8Encoding $false)) New-Item -ItemType Directory -Force -Path $OutDir | Out-Null $MsixPath = Join-Path $OutDir ("Navis_" + $Version + ".msix") if (Test-Path $MsixPath) { Remove-Item -Force $MsixPath } if (-not $MakeAppx) { Write-Host "" Write-Host "MakeAppx.exe not found - install the Windows 10/11 SDK to produce .msix." -ForegroundColor Yellow Write-Host "Staging is ready: $Staging" Write-Host "Then run:" Write-Host (" makeappx pack /d `"{0}`" /p `"{1}`" /o" -f $Staging, $MsixPath) exit 2 } Write-Host "Packing $MsixPath ..." & $MakeAppx pack /d $Staging /p $MsixPath /o if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } if ($CertPath) { $SignTool = Find-SdkTool "signtool.exe" if (-not $SignTool) { throw "signtool.exe not found (needed for -CertPath)." } Write-Host "Signing with $CertPath ..." if ($CertPassword) { & $SignTool sign /fd SHA256 /a /f $CertPath /p $CertPassword $MsixPath } else { & $SignTool sign /fd SHA256 /a /f $CertPath $MsixPath } if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } } Write-Host "" Write-Host "Done:" Write-Host " $MsixPath" Write-Host " Staging: $Staging" Write-Host "" Write-Host "Store: upload MSIX in Partner Center (identity must match reservation)." Write-Host ("Sideload: Add-AppxPackage -Path `"{0}`"" -f $MsixPath)