<# .SYNOPSIS Build the Windows "MSIX" package: same feature set as Full (bundled node + ffmpeg), packaged for Microsoft Store submission instead of NSIS. .DESCRIPTION See C:\Users\admin\devel\msix-installer.md for the plan this implements. Unlike Light, this target does NOT drop anything from Full's feature set -- it exists because Store certification of the NSIS "MSI/EXE" submission failed for a reason MSIX sidesteps entirely (an unsigned, internet-downloaded installer never gets a chance to run under Microsoft's own unattended validation bot; see msix-installer.md ยง2), not because the bundled node/service-mode/autostart machinery needed removing. The one real change is *when* the two elevated operations (firewall rule, service-mode install) can happen: an AppX/MSIX install never elevates, so neither can run at install time the way build/installer.nsh's customInstall macro does. Both already have an elevation path that does not depend on the installer at all -- firewall.ps1's own per-first-use Windows prompt, and main.js's winElevateServiceMode() ("the other door", already used by the Node page today) -- so nothing in src/main.js needed to change for this target to work. Steps 1-5 are identical to build-win.ps1 (build-win-common.ps1 for 1-4, build-node-runtime.ps1 for 5 -- this target ships the same frozen daemon Full does). Step 6 hands electron-builder a standalone config (electron-builder.msix.yml) via --config, same reasoning as Light: the two targets' extraResources and signing configuration must never merge. Output: packages/meshbay-client/dist-msix/MeshBay-.appx .PARAMETER SkipFfmpeg Passed through to build-node-runtime.ps1 -- skip bundling ffmpeg. Smaller, streaming-less build for local iteration only. .PARAMETER NoElectronBump Keep the pinned Electron instead of upgrading to the latest release. .PARAMETER SkipNodeRuntime Reuse an existing packages/meshbay-client/node-runtime/ (faster iteration on the electron-builder side). #> [CmdletBinding()] param( [switch]$SkipFfmpeg, [switch]$NoElectronBump, [switch]$SkipNodeRuntime ) $ErrorActionPreference = "Stop" Set-StrictMode -Version Latest $WinDir = $PSScriptRoot $Repo = (Resolve-Path (Join-Path $WinDir "..\..")).Path $Client = Join-Path $Repo "packages\meshbay-client" $Config = Join-Path $WinDir "electron-builder.msix.yml" . (Join-Path $WinDir "build-win-common.ps1") if (-not (Test-Path $Config)) { throw "missing $Config" } # electron-builder's AppX target downloads its own bundled Windows Kits tools # (winCodeSign-*.7z) unless ELECTRON_BUILDER_WINDOWS_KITS_PATH already points # at a real one. That archive's 7z extraction creates symlinks for binaries # this target never uses (its macOS/Linux signing tools), and fails outright # without SeCreateSymbolicLinkPrivilege -- which this machine's build shell # does not hold. The Windows 10 SDK already installed here has everything # actually needed (makeappx.exe, signtool.exe); point electron-builder at # it instead of fighting that extraction. Only set if the caller hasn't # already pointed it somewhere themselves. if (-not $env:ELECTRON_BUILDER_WINDOWS_KITS_PATH) { $kitsRoot = "C:\Program Files (x86)\Windows Kits\10\bin" $kit = Get-ChildItem $kitsRoot -ErrorAction SilentlyContinue | Where-Object { $_.PSIsContainer -and $_.Name -match '^\d+\.\d+\.\d+\.\d+$' ` -and (Test-Path (Join-Path $_.FullName "x64\makeappx.exe")) } | Sort-Object Name -Descending | Select-Object -First 1 if (-not $kit) { throw ("No Windows 10 SDK with makeappx.exe found under $kitsRoot -- " + "install the Windows 10 SDK (the App Certification Kit / MSIX " + "Packaging Tools component covers it), or set " + "ELECTRON_BUILDER_WINDOWS_KITS_PATH yourself.") } $env:ELECTRON_BUILDER_WINDOWS_KITS_PATH = Join-Path $kit.FullName "x64" } Step "Windows Kits: $env:ELECTRON_BUILDER_WINDOWS_KITS_PATH" # --- 1. Node ------------------------------------------------------------- Assert-NodeVersion Push-Location $Client try { # --- 2. deps ------------------------------------------------------ Invoke-NpmCi # --- 3. Electron: build against the latest release -------------- Invoke-ElectronBump -NoElectronBump:$NoElectronBump -WinDir $WinDir # --- 4. UI ----------------------------------------------------- Invoke-SyncUi # --- 5. node runtime --------------------------------------- $rtExe = Join-Path $Client "node-runtime\meshbay-node.exe" if ($SkipNodeRuntime -and (Test-Path $rtExe)) { Step "reusing existing node-runtime/" } else { Step "building the bundled node (PyInstaller)" $rtArgs = @{} if ($SkipFfmpeg) { $rtArgs["SkipFfmpeg"] = $true } & (Join-Path $WinDir "build-node-runtime.ps1") @rtArgs if ($LASTEXITCODE -ne 0) { throw "build-node-runtime.ps1 failed" } } # --- 6. package --------------------------------------- Step "electron-builder --win appx --config electron-builder.msix.yml" & npx electron-builder --win appx --config $Config if ($LASTEXITCODE -ne 0) { throw "electron-builder failed" } } finally { Pop-Location } $pkg = Get-ChildItem (Join-Path $Client "dist-msix") -Filter "*.appx" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime | Select-Object -Last 1 Write-Host "" if ($pkg) { Write-Host "OK package: $($pkg.FullName)" -ForegroundColor Green Write-Host (" ({0:N0} MB)" -f ($pkg.Length / 1MB)) Write-Host " unsigned by design -- Microsoft signs it at publish time" -ForegroundColor DarkGray Write-Host " (msix-installer.md 3)." -ForegroundColor DarkGray } else { Write-Host "!! no *.appx found in $Client\dist-msix" -ForegroundColor Red exit 1 }