22# Weather Widget - MSIX Package Builder (Microsoft Store)
33# ============================================================================
44# Usage:
5- # .\installer\build-msix.ps1 -Version "1.0.0.0"
5+ # # For Microsoft Store submission (unsigned — Store signs it for you):
6+ # .\installer\build-msix.ps1 -Version "1.0.0.0" -StoreUpload
7+ #
8+ # # For local testing with self-signed cert:
69# .\installer\build-msix.ps1 -Version "1.0.0.0" -CertPath "cert.pfx" -CertPassword "pass"
10+ #
11+ # # For local testing without signing:
712# .\installer\build-msix.ps1 -Version "1.0.0.0" -SkipSign
813#
914# Prerequisites:
1015# - Go 1.25+ with CGO enabled (for Fyne)
1116# - go-winres: go install github.com/tc-hib/go-winres@latest
1217# - Windows SDK (for MakeAppx.exe and SignTool.exe)
13- # - Code signing certificate (for production builds)
18+ # - Code signing certificate (only for local/sideload builds)
19+ #
20+ # Microsoft Store Notes:
21+ # - Use -StoreUpload to produce an .msixupload file for Partner Center.
22+ # - The Store signs the package — you do NOT need a certificate for submission.
23+ # - The AppxManifest.xml Identity Name and Publisher must match Partner Center
24+ # values exactly. Check Partner Center > Product Identity for your values.
25+ # - Partner Center App ID: 47955afa-afc7-46ee-abc1-02ab2632b4ad
1426# ============================================================================
1527
1628param (
2032 [string ]$CertPath = " " ,
2133 [string ]$CertPassword = " " ,
2234 [switch ]$SkipSign ,
23- [switch ]$SkipBuild
35+ [switch ]$SkipBuild ,
36+ [switch ]$StoreUpload
2437)
2538
2639$ErrorActionPreference = " Stop"
@@ -42,17 +55,28 @@ try {
4255 $BuildDir = " .\build"
4356 $PackageDir = " .\build\package"
4457 $OutputMsix = " .\build\WeatherWidget-$Version .msix"
58+ $OutputMsixUpload = " .\build\WeatherWidget-$Version .msixupload"
59+
60+ # Determine total steps based on mode
61+ if ($StoreUpload ) {
62+ $totalSteps = 7
63+ } else {
64+ $totalSteps = 6
65+ }
4566
4667 Write-Host " "
4768 Write-Host " ============================================" - ForegroundColor Cyan
4869 Write-Host " Weather Widget MSIX Builder v$Version " - ForegroundColor Cyan
70+ if ($StoreUpload ) {
71+ Write-Host " Mode: Microsoft Store Upload" - ForegroundColor Cyan
72+ }
4973 Write-Host " ============================================" - ForegroundColor Cyan
5074 Write-Host " "
5175
5276 # -------------------------------------------------------------------------
5377 # Step 1: Clean previous build
5478 # -------------------------------------------------------------------------
55- Write-Host " [1/6 ] Cleaning previous build..." - ForegroundColor Yellow
79+ Write-Host " [1/$totalSteps ] Cleaning previous build..." - ForegroundColor Yellow
5680 if (Test-Path $BuildDir ) { Remove-Item - Recurse - Force $BuildDir }
5781 New-Item - ItemType Directory - Path $PackageDir - Force | Out-Null
5882 New-Item - ItemType Directory - Path " $PackageDir \assets" - Force | Out-Null
6286 # Step 2: Generate Windows resources (icon, manifest, version info)
6387 # -------------------------------------------------------------------------
6488 if (-not $SkipBuild ) {
65- Write-Host " [2/6 ] Generating Windows resources..." - ForegroundColor Yellow
89+ Write-Host " [2/$totalSteps ] Generating Windows resources..." - ForegroundColor Yellow
6690
6791 # Update version in winres.json before generating
6892 $winresJson = Get-Content " .\winres\winres.json" - Raw | ConvertFrom-Json
79103 # ---------------------------------------------------------------------
80104 # Step 3: Build the executable
81105 # ---------------------------------------------------------------------
82- Write-Host " [3/6 ] Building weatherwidget.exe..." - ForegroundColor Yellow
106+ Write-Host " [3/$totalSteps ] Building weatherwidget.exe..." - ForegroundColor Yellow
83107 $env: GOOS = " windows"
84108 $env: GOARCH = " amd64"
85109 $env: CGO_ENABLED = " 1"
@@ -89,18 +113,20 @@ try {
89113 if ($LASTEXITCODE -ne 0 ) { throw " Go build failed" }
90114 Write-Host " Done. Output: $BuildDir \weatherwidget.exe" - ForegroundColor Green
91115 } else {
92- Write-Host " [2/6 ] Skipping resource generation (SkipBuild)." - ForegroundColor DarkGray
93- Write-Host " [3/6 ] Skipping build (SkipBuild)." - ForegroundColor DarkGray
116+ Write-Host " [2/$totalSteps ] Skipping resource generation (SkipBuild)." - ForegroundColor DarkGray
117+ Write-Host " [3/$totalSteps ] Skipping build (SkipBuild)." - ForegroundColor DarkGray
94118 if (-not (Test-Path " $BuildDir \weatherwidget.exe" )) {
95119 throw " No existing exe found at $BuildDir \weatherwidget.exe. Remove -SkipBuild flag."
96120 }
97121 }
98122
99123 # -------------------------------------------------------------------------
100- # Step 4: Sign the executable
124+ # Step 4: Sign the executable (skip for Store uploads)
101125 # -------------------------------------------------------------------------
102- if (-not $SkipSign -and $CertPath ) {
103- Write-Host " [4/6] Signing executable..." - ForegroundColor Yellow
126+ if ($StoreUpload ) {
127+ Write-Host " [4/$totalSteps ] Skipping exe signing (Store signs the package)." - ForegroundColor DarkGray
128+ } elseif (-not $SkipSign -and $CertPath ) {
129+ Write-Host " [4/$totalSteps ] Signing executable..." - ForegroundColor Yellow
104130 $signArgs = @ (
105131 " sign" , " /fd" , " SHA256" ,
106132 " /tr" , " http://timestamp.digicert.com" ,
@@ -114,13 +140,13 @@ try {
114140 if ($LASTEXITCODE -ne 0 ) { throw " Executable signing failed" }
115141 Write-Host " Done." - ForegroundColor Green
116142 } else {
117- Write-Host " [4/6 ] Skipping exe signing." - ForegroundColor DarkGray
143+ Write-Host " [4/$totalSteps ] Skipping exe signing." - ForegroundColor DarkGray
118144 }
119145
120146 # -------------------------------------------------------------------------
121147 # Step 5: Assemble MSIX package layout
122148 # -------------------------------------------------------------------------
123- Write-Host " [5/6 ] Assembling package layout..." - ForegroundColor Yellow
149+ Write-Host " [5/$totalSteps ] Assembling package layout..." - ForegroundColor Yellow
124150
125151 # Copy exe
126152 Copy-Item " $BuildDir \weatherwidget.exe" " $PackageDir \"
@@ -150,9 +176,9 @@ try {
150176 Write-Host " Done." - ForegroundColor Green
151177
152178 # -------------------------------------------------------------------------
153- # Step 6: Create and sign MSIX
179+ # Step 6: Create MSIX package
154180 # -------------------------------------------------------------------------
155- Write-Host " [6/6 ] Creating MSIX package..." - ForegroundColor Yellow
181+ Write-Host " [6/$totalSteps ] Creating MSIX package..." - ForegroundColor Yellow
156182
157183 # Find MakeAppx.exe from Windows SDK
158184 $sdkPaths = @ (
@@ -182,9 +208,14 @@ try {
182208
183209 & $makeAppx pack / d $PackageDir / p $OutputMsix / o
184210 if ($LASTEXITCODE -ne 0 ) { throw " MakeAppx failed" }
211+ Write-Host " Done." - ForegroundColor Green
185212
186- # Sign the MSIX
187- if (-not $SkipSign -and $CertPath ) {
213+ # -------------------------------------------------------------------------
214+ # Step 6b: Sign the MSIX (local/sideload only — not for Store)
215+ # -------------------------------------------------------------------------
216+ if ($StoreUpload ) {
217+ # No signing needed — Partner Center signs Store packages
218+ } elseif (-not $SkipSign -and $CertPath ) {
188219 Write-Host " Signing MSIX..." - ForegroundColor Yellow
189220 $signArgs = @ (
190221 " sign" , " /fd" , " SHA256" ,
@@ -197,17 +228,50 @@ try {
197228
198229 & signtool @signArgs
199230 if ($LASTEXITCODE -ne 0 ) { throw " MSIX signing failed" }
231+ Write-Host " Signed." - ForegroundColor Green
232+ }
233+
234+ # -------------------------------------------------------------------------
235+ # Step 7 (Store only): Create .msixupload for Partner Center
236+ # -------------------------------------------------------------------------
237+ if ($StoreUpload ) {
238+ Write-Host " [7/$totalSteps ] Creating .msixupload for Partner Center..." - ForegroundColor Yellow
239+
240+ # .msixupload is a ZIP containing the .msix (and optionally .msixsym)
241+ # Partner Center expects this format for Store submissions.
242+ if (Test-Path $OutputMsixUpload ) { Remove-Item $OutputMsixUpload - Force }
243+ Compress-Archive - Path $OutputMsix - DestinationPath $OutputMsixUpload - Force
244+
245+ Write-Host " Done." - ForegroundColor Green
200246 }
201247
248+ # -------------------------------------------------------------------------
249+ # Summary
250+ # -------------------------------------------------------------------------
202251 Write-Host " "
203252 Write-Host " ============================================" - ForegroundColor Green
204253 Write-Host " BUILD SUCCESSFUL" - ForegroundColor Green
205- Write-Host " Output: $OutputMsix " - ForegroundColor Green
254+ Write-Host " MSIX: $OutputMsix " - ForegroundColor Green
255+ if ($StoreUpload ) {
256+ Write-Host " Upload: $OutputMsixUpload " - ForegroundColor Green
257+ }
206258 Write-Host " ============================================" - ForegroundColor Green
207259 Write-Host " "
208260
209- if ($SkipSign -or -not $CertPath ) {
210- Write-Host " NOTE: Package is unsigned. For Store submission," - ForegroundColor Yellow
261+ if ($StoreUpload ) {
262+ Write-Host " NEXT STEPS for Microsoft Store submission:" - ForegroundColor Cyan
263+ Write-Host " 1. Verify AppxManifest.xml Identity Name and Publisher" - ForegroundColor White
264+ Write-Host " match your Partner Center > Product Identity values." - ForegroundColor White
265+ Write-Host " 2. Replace placeholder store assets in installer\store-assets\" - ForegroundColor White
266+ Write-Host " with properly sized PNGs before final submission." - ForegroundColor White
267+ Write-Host " 3. Upload $OutputMsixUpload to Partner Center." - ForegroundColor White
268+ Write-Host " (Partner Center > Your App > Packages)" - ForegroundColor White
269+ Write-Host " 4. Microsoft will sign the package during certification." - ForegroundColor White
270+ Write-Host " "
271+ Write-Host " Partner Center App ID: 47955afa-afc7-46ee-abc1-02ab2632b4ad" - ForegroundColor DarkGray
272+ Write-Host " "
273+ } elseif ($SkipSign -or -not $CertPath ) {
274+ Write-Host " NOTE: Package is unsigned. For sideloading," - ForegroundColor Yellow
211275 Write-Host " provide -CertPath and -CertPassword parameters." - ForegroundColor Yellow
212276 Write-Host " "
213277 }
0 commit comments