winapp-package
Bir Windows uygulamasını dağıtım veya test için MSIX yükleyicisi olarak paketleyin. Bir Windows yükleyicisi oluştururken, bir uygulamayı paketlerken…
npx skills add https://github.com/microsoft/winappcli --skill winapp-packageWhen to use
Use this skill when:
- Creating an MSIX installer from a built app for distribution or testing
- Packaging any Windows app — GUI apps, console apps, CLI tools, services, or background processes
- Signing a package with a development or production certificate
- Bundling the Windows App SDK runtime for self-contained deployment
Prerequisites
Before packaging, you need:
- Built app output in a folder (e.g.,
bin/Release/,dist/,build/) Package.appxmanifest— fromwinapp initorwinapp manifest generate- Certificate (optional) —
devcert.pfxfromwinapp cert generatefor signing
Usage
Basic packaging (unsigned)
# Package from build output — manifest auto-detected from current dir or input folder
winapp package ./bin/Release
# Specify manifest location explicitly
winapp package ./dist --manifest ./Package.appxmanifest
Package and sign in one step
# Sign with existing certificate
winapp package ./bin/Release --cert ./devcert.pfx
# Custom certificate password
winapp package ./bin/Release --cert ./devcert.pfx --cert-password MyP@ssw0rd
Generate certificate + package in one step
# Auto-generate cert, sign, and package
winapp package ./bin/Release --generate-cert
# Also install the cert to trust it on this machine (requires admin)
winapp package ./bin/Release --generate-cert --install-cert
Self-contained deployment
# Bundle Windows App SDK runtime so users don't need it installed (must have winappsdk reference in the winapp.yaml or *.csproj)
winapp package ./bin/Release --cert ./devcert.pfx --self-contained
Custom output path and name
# Specify output file
winapp package ./dist --output ./releases/myapp-v1.0.msix --cert ./devcert.pfx
# Custom package name
winapp package ./dist --name "MyApp_1.0.0_x64" --cert ./devcert.pfx
What the command does
- Locates
Package.appxmanifest— looks in input folder, then current directory (or uses--manifest) - Copies manifest + assets into a staging layout alongside your app files
- Discovers manifest-referenced files — any non-image file referenced in the manifest (e.g., AppExtension payloads like
manifest.json, config files) is automatically copied from the manifest directory or input folder if missing from staging - Generates
resources.pri— Package Resource Index for UWP-style resource lookup (skip with--skip-pri) - Runs
makeappx pack— creates the.msixpackage file - Signs the package (if
--certprovided) — callssigntoolwith your certificate
Output: a .msix file that can be installed on Windows via double-click or Add-AppxPackage.
Installing the MSIX for testing
# Trust the dev certificate first (one-time, requires admin)
winapp cert install ./devcert.pfx
# Install the MSIX
Add-AppxPackage ./myapp.msix
# Uninstall if needed
Get-AppxPackage *myapp* | Remove-AppxPackage
Recommended workflow
- Build your app (
dotnet build,cmake --build,npm run make, etc.) - Package —
winapp package <build-output> --cert ./devcert.pfx - Trust cert (first time) —
winapp cert install ./devcert.pfx(admin) - Install — double-click the
.msixorAdd-AppxPackage ./myapp.msix - Test the installed app from the Start menu
Advanced: External content catalog
For sparse packages with AllowExternalContent, you may need a code integrity catalog:
# Generate CodeIntegrityExternal.cat for external executables
winapp create-external-catalog "./bin/Release"
# Include subdirectories and specify output path
winapp create-external-catalog "./bin/Release" --recursive --output ./catalog/CodeIntegrityExternal.cat
Bundling multiple architectures
Create an MSIX bundle from multiple per-architecture build outputs:
# Create unsigned bundle for Store submission (x64 + arm64)
winapp package ./publish/x64 ./publish/arm64
# Create signed bundle for sideloading
winapp package ./publish/x64 ./publish/arm64 --cert ./devcert.pfx
# Self-contained bundle with Windows App SDK runtime per arch
winapp package ./publish/x64 ./publish/arm64 --self-contained --generate-cert
How it works: When multiple input folders are passed, winapp package:
- Detects the architecture of each folder's primary executable from its PE header
- Resolves a manifest for each slice (see below)
- Validates that all slices share the same Identity, Capabilities, and Dependencies
- Packs each folder into an intermediate unsigned
.msix - Bundles them into a single
.msixbundleusingmakeappx bundle - Signs only the bundle (not individual slices) — the signature covers all packages inside
Manifest resolution: Each slice needs a manifest. Resolution order:
--manifest <path>uses one manifest for all slices (architecture auto-stamped per folder)- Per-folder
Package.appxmanifestif present in the input folder - Fallback to
Package.appxmanifestin the current working directory
The ProcessorArchitecture is always force-set to the detected architecture per-slice. All other Identity fields must be consistent across slices.
Output: <Name>_<Version>_<arch1>_<arch2>.msixbundle (architectures sorted alphabetically).
Store submission: An unsigned bundle is valid for Store upload — Partner Center signs it with your reserved identity certificate. For sideloading, pass --cert or --generate-cert.
This hashes executables in the specified directories so Windows trusts them when running with sparse package identity.
CI/CD
GitHub Actions
Use the microsoft/setup-winapp action to install winapp on GitHub-hosted runners:
- uses: microsoft/setup-winapp@v1
- name: Package
run: winapp package ./dist --cert ${{ secrets.CERT_PATH }} --cert-password ${{ secrets.CERT_PASSWORD }} --quiet
Tips for CI/CD pipelines:
- Use
--quiet(or-q) to suppress progress output - Use
--if-exists skipwithwinapp cert generateto avoid regenerating existing certificates - Store your PFX certificate as a repository secret and decode it in CI
- Use
--use-defaults(or--no-prompt) withwinapp initto avoid interactive prompts
Tips
- The
packagecommand aliases topack— both work identically Package.appxmanifestPublisher must match the certificate publisher — usewinapp cert generate --manifestto ensure they match- Use
--skip-priif your app doesn't use Windows resource loading (e.g., most Electron/Rust/C++ apps without UWP resources) - For framework-specific packaging paths (Electron, .NET, Rust, etc.), see the
winapp-frameworksskill - The
--executableflag overrides the entry point in the manifest — useful when your exe name differs from what's inPackage.appxmanifest - For production distribution, use a certificate from a trusted CA and add
--timestampwhen signing withwinapp sign
Sparse identity packages
To grant identity to an app distributed by an existing installer (not as MSIX), build an identity-only sparse package: pass a sparse appxmanifest.xml (one declaring <uap10:AllowExternalContent>true</uap10:AllowExternalContent> under <Properties>) to winapp pack instead of a folder.
# 1. Generate the sparse manifest for your exe (skips SDK install)
winapp init --exe ./bin/Release/MyApp.exe --sparse --use-defaults
# 2. Build & sign the identity-only .msix (just the manifest)
winapp pack ./sparse/appxmanifest.xml --cert ./devcert.pfx
# 3. Embed identity into the exe, then register in your installer
winapp embed-identity ./bin/Release/MyApp.exe
The .msix contains only the manifest — binaries and assets are resolved from the external content location at runtime via Add-AppxPackage -ExternalLocation. If you pack a folder whose manifest declares AllowExternalContent, winapp pack warns about any assets/binaries found. See the Sparse Packaging Guide.
Related skills
- Need a manifest first? See
winapp-manifestto generatePackage.appxmanifest - Need a certificate? See
winapp-signingfor certificate generation and management - Having issues? See
winapp-troubleshootfor a command selection flowchart and error solutions
Troubleshooting
| Error | Cause | Solution |
|---|---|---|
| "Package.appxmanifest not found" | No manifest in input folder or current dir | Run winapp init or winapp manifest generate first |
| "Publisher mismatch" | Cert publisher ≠ manifest publisher | Regenerate cert with winapp cert generate --manifest, or edit manifest |
| "Package installation failed" | Cert not trusted or stale package | Run winapp cert install ./devcert.pfx (admin), then Get-AppxPackage <name> | Remove-AppxPackage |
| "makeappx not found" | Build tools not downloaded | Run winapp update or winapp tool makeappx --help to trigger download |
CLI reference
Run winapp <command> --help for current command options, or winapp --cli-schema for the complete machine-readable command schema.