This post was entirely generated by AI.
Overview
The Microsoft Windows SDK BuildTools MSIX package provides comprehensive build system support for creating and packaging Windows applications as MSIX/APPX packages. This package integrates with MSBuild to enable:
- Single-Project MSIX Packaging: Build and package applications as MSIX in a single project file
- Package Management: Full control over package generation, signing, and deployment
- Resource Management (PRI): Automatic resource indexing and localization support
- Bundle Support: Create app bundles for distribution
- Store Publishing: Generate upload packages for Microsoft Store
- Manifest Handling: Automatic AppxManifest generation and validation
- Signing & Security: Certificate-based code signing and Azure key vault integration
- Layout & Deployment: Support for sparse packages and custom deployment layouts
Supported Project Types:
- C# / .NET projects (.csproj)
- C++ / Native projects (.vcxproj)
- Modern .NET 6/7/8+ projects
- Classic .NET Framework projects
Required Properties
These properties MUST be set for MSIX packaging to work:
EnableMsixTooling (or EnablePreviewMsixTooling)
- Type: Boolean (
true/false) - Required: YES (for non-.wapproj projects)
- Default:
false - Purpose: Master flag that activates the MSIX tooling for the project. Without this, the tooling is completely disabled.
- Usage:
<PropertyGroup> <EnableMsixTooling>true</EnableMsixTooling> </PropertyGroup> - Note:
EnablePreviewMsixToolingis the legacy name from older WindowsAppSDK releases, still supported for compatibility.
Package.appxmanifest (File)
- Type: File (must exist in project root)
- Required: YES (for MSIX WindowsPackageType)
- Default: Auto-detected if exists
- Purpose: The application manifest defining app identity, capabilities, and configuration
- Location: Typically in project root
- Usage: Include in project as
<AppxManifest Include="Package.appxmanifest" />
WindowsPackageType
- Type: String enum
- Required: YES (for packaged apps)
- Default:
None(unless Package.appxmanifest exists →MSIX) - Valid Values:
None: No packaging (traditional Win32 app)MSIX: Full MSIX package with identitySparse: MSIX with identity but minimal content (for multi-project scenarios)
- Purpose: Defines the type of package to create and application model
- Usage:
<PropertyGroup> <WindowsPackageType>MSIX</WindowsPackageType> </PropertyGroup>
Optional Properties
Package Generation & Signing
GenerateAppxPackageOnBuild
- Type: Boolean
- Default:
false - Possible Values:
true,false - Purpose: Automatically generate the MSIX/APPX package during every build
- When to Use: CI/CD pipelines, automated builds
- Usage:
<PropertyGroup> <GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild> </PropertyGroup>
PublishAppxPackage
- Type: Boolean
- Default:
false - Possible Values:
true,false - Purpose: Trigger MSIX generation during the Publish build target
- When to Use: When publishing to Microsoft Store or deployment servers
AppxPackage
- Type: Boolean
- Default:
true(if OutputType is WinExe/Exe and WindowsPackageType != None) - Purpose: Explicitly enable/disable package generation for this project
- Note: Usually auto-determined; only override for special scenarios
AppxPackageDir
- Type: Path
- Default:
$(ProjectDir)AppPackages\or$(OutDir)AppPackages\ - Purpose: Output directory for generated packages
- Usage:
<PropertyGroup> <AppxPackageDir>C:\MyPackages\</AppxPackageDir> </PropertyGroup>
AppxPackageDirName
- Type: String
- Default:
AppPackages - Purpose: Folder name (not full path) for package output
- Note: Used when
AppxPackageDiris not explicitly set
Signing & Security Properties
AppxPackageSigningEnabled
- Type: Boolean
- Default:
true(ifPackageCertificateKeyFileexists) - Purpose: Enable/disable package signing
- When to Use: Always enabled; disable only for debug/test scenarios
PackageCertificateKeyFile
- Type: File path
- Default: (empty)
- Purpose: Path to .pfx certificate file for signing packages
- Usage:
<PropertyGroup> <PackageCertificateKeyFile>$(ProjectDir)MySigningCert.pfx</PackageCertificateKeyFile> <PackageCertificatePassword>YourCertPassword</PackageCertificatePassword> </PropertyGroup> - Note: Required for Store submission
PackageCertificatePassword
- Type: String (password)
- Default: (empty)
- Purpose: Password for the certificate file
- Security: Consider using environment variables or secure build variables
- Usage:
<PropertyGroup> <PackageCertificatePassword>$(CertPassword)</PackageCertificatePassword> </PropertyGroup>
PackageCertificateThumbprint
- Type: String (hex thumbprint)
- Default: (empty)
- Purpose: Thumbprint of installed certificate for signing
- Usage: Alternative to
PackageCertificateKeyFilewhen certificate is in certificate store - Format: 40-character hex string (without spaces)
EnableSigningChecks
- Type: Boolean
- Default:
true - Purpose: Enable validation of signing certificate and publisher name
- Note: Disable only for internal/test builds
AppxPackageSigningTimestampServerUrl
- Type: URL
- Default: (empty)
- Purpose: Time-stamping server for signed packages (for archive integrity)
- Example:
http://timestamp.digicert.com - Note: Optional; provides cryptographic timestamp to package
AppxPackageSigningTimestampDigestAlgorithm
- Type: String
- Default:
sha256 - Possible Values:
sha1,sha256,sha384,sha512 - Purpose: Hash algorithm for timestamp digest
GenerateTemporaryStoreCertificate
- Type: Boolean
- Default:
false - Purpose: Auto-generate temporary certificate for store upload builds
- When to Use: When no certificate is available but building for store upload
Azure Code Signing
AzureCodeSigningEnabled
- Type: Boolean
- Default:
false - Purpose: Use Azure Code Signing service instead of local certificate
- Prerequisites: Azure Trusted Signing account
- Related: Set automatically when
AzureCodeSigningDlibVersionis set
AzureCodeSigningDlibVersion
- Type: Version string
- Default: (empty)
- Purpose: Version of Azure Code Signing DLL to use
- Sets:
AzureCodeSigningEnabled=trueautomatically
AzureCodeSigningEndpoint
- Type: URL
- Default: (empty)
- Purpose: Azure Trusted Signing endpoint URL
AzureCodeSigningAccountName
- Type: String
- Default: (empty)
- Purpose: Azure account name for code signing
AzureCodeSigningCertificateProfileName
- Type: String
- Default: (empty)
- Purpose: Certificate profile name in Azure Trusted Signing
Azure Key Vault Integration
AzureKeyVaultEnabled
- Type: Boolean
- Default:
false - Purpose: Use Azure Key Vault for certificate storage
- Set Automatically: When both
AzureKeyVaultUrlandAzureKeyVaultCertificateIdare set
AzureKeyVaultUrl
- Type: URL
- Default: (empty)
- Purpose: Azure Key Vault URL
- Format:
https://<vault-name>.vault.azure.net/
AzureKeyVaultCertificateId
- Type: String
- Default: (empty)
- Purpose: Certificate identifier in Key Vault
- Format:
certificates/<certificate-name>/or full certificate URI
Package Bundling & Deployment
AppxBundle
- Type: String enum
- Default: (empty / not set)
- Possible Values:
Always: Create bundle every buildAuto: Create bundle for Store builds- (empty): No bundle
- Purpose: Control app bundle generation (.appxbundle / .msixbundle)
- Usage:
<PropertyGroup> <AppxBundle>Always</AppxBundle> </PropertyGroup>
UapAppxPackageBuildMode
- Type: String enum
- Default: (empty)
- Possible Values:
StoreAndSideload: Generate both Store (.msixupload) and sideload packagesSideloadOnly: Generate only sideload package (.msix)StoreOnly: Generate only Store package (.msixupload)
- Purpose: Choose packaging scenario (store vs. sideload vs. both)
- Usage:
<PropertyGroup> <UapAppxPackageBuildMode>StoreAndSideload</UapAppxPackageBuildMode> </PropertyGroup>
BuildAppxUploadPackageForUap
- Type: Boolean
- Default: Auto-determined based on build mode and configuration
- Purpose: Generate .msixupload file for Store submission
- Note: Not generated for Debug builds
BuildAppxSideloadPackageForUap
- Type: Boolean
- Default: Auto-determined
- Purpose: Generate sideload .msix package
AppxPackageUploadDir
- Type: Path
- Default:
$(OutDir)Upload\$(AppxPackageDirName)\ - Purpose: Output directory for upload packages (.msixupload)
AppxPackageUploadDirName
- Type: String
- Default:
Upload - Purpose: Folder name for upload packages
Resource & Localization (PRI)
AppxGeneratePriEnabled
- Type: Boolean
- Default:
true - Purpose: Enable PRI (Package Resource Index) generation
- When to Use: Always enabled for modern apps with resources
ProjectPriFileName
- Type: String
- Default:
resources.pri(for apps) or$(ProjectName).pri(for libraries) - Purpose: Output filename for the PRI file
ProjectPriFullPath
- Type: Path
- Default:
$(TargetDir)$(AppxPackageArtifactsDir)$(ProjectPriFileName) - Purpose: Full output path for PRI file
AppxDefaultResourceQualifierUAP_Language
- Type: String
- Default:
{DefaultResourceLanguage} - Purpose: Default language for resource qualifiers
AppxDefaultResourceQualifierUAP_Scale
- Type: String enum
- Default:
200(200% DPI) - Possible Values:
100,125,150,200,400 - Purpose: Default display scale qualifier
AppxBundleAutoResourcePackageQualifiers
- Type: String (pipe-separated)
- Default:
Language|Scale|DXFeatureLevel - Purpose: Resource qualifiers for automatic resource package splitting in bundles
- Usage: Control what dimensions cause separate resource packages
EnableDefaultPriItems
- Type: Boolean
- Default:
true - Purpose: Auto-include .resw (resource) and .xaml files in PRI generation
ShouldComputeInputPris
- Type: Boolean
- Default:
true(for apps),false(for libraries) - Purpose: Merge PRI files from referenced projects into main PRI
Layout & Payload
LayoutDir
- Type: Path
- Default:
$(TargetDir)AppX - Purpose: Directory for package layout/structure before packaging
AppxLayoutEnabled
- Type: Boolean
- Default:
false - Purpose: Use PackageLayout files for advanced layout control
- Prerequisites: Operating on Windows 10 RS4 or later
AppxLayoutFileName
- Type: String
- Default:
App.packagelayout - Purpose: Filename for package layout template
UseAppxLayout
- Type: Boolean
- Default:
false - Purpose: Read and apply layout from PackageLayout file
AppxLayoutDir
- Type: Path
- Default:
$(IntermediateOutputPath)PackageLayout\ - Purpose: Intermediate directory for layout processing
GenerateLibraryLayout
- Type: Boolean
- Default:
true(for non-executable projects) - Purpose: Generate layout directory for library projects
- Usage: Needed when library is referenced by app project
RemoveNonLayoutFiles
- Type: Boolean
- Default:
true - Purpose: Remove files that aren't part of official layout
AppxSkipUnchangedFiles
- Type: Boolean
- Default:
true - Purpose: Skip copying files to package layout if unchanged
- Benefit: Speeds up incremental builds
Symbol Packages & Debugging
AppxSymbolPackageEnabled
- Type: Boolean
- Default:
true - Purpose: Generate .appxsym symbol package for debugging
- When to Use: Always for release builds
AppxPackageIncludePrivateSymbols
- Type: Boolean
- Default:
false - Purpose: Include private symbols in symbol package
AppxSymbolIntermediateDir
- Type: Path
- Default:
$(IntermediateOutputPath)Symbols - Purpose: Intermediate directory for symbol processing
Manifest & Content Validation
AppxStrictManifestValidationEnabled
- Type: Boolean
- Default:
true - Purpose: Perform strict validation on AppxManifest
- Disable For: Testing only; keep enabled for production
AppxPackageValidationEnabled
- Type: Boolean
- Default:
true - Purpose: Validate package structure and contents
DisableAppxManifestItemPackageContentValidation
- Type: Boolean
- Default:
false - Purpose: Skip validation of manifest-declared content items
- Note: Usually keep enabled for safety
SkipPublisherNameValidation
- Type: Boolean
- Default:
false - Purpose: Skip publisher name validation against certificate
- When to Use: Using Azure Code Signing or Key Vault
Advanced Payload Management
AppxUseHardlinksIfPossible
- Type: Boolean
- Default:
false - Purpose: Use hardlinks instead of copies in layout (faster, requires same filesystem)
AppxUseHardlinksForNugetIfPossible
- Type: Boolean
- Default:
false - Purpose: Use hardlinks for NuGet package files specifically
AppxRemoveRedundantCopyLocalItems
- Type: Boolean
- Default:
true - Purpose: Remove duplicate/redundant items from package payload
IncludeDocumentationFilesInAppxPackage
- Type: Boolean
- Default:
false - Purpose: Include XML documentation files in package
- Note: Usually false to reduce package size
AppxFilterOutUnusedLanguagesResourceFileMaps
- Type: Boolean
- Default:
true - Purpose: Exclude unused language resource files from bundle
AppxExcludeXamlFromLibraryLayoutsWhenXbfIsPresent
- Type: Boolean
- Default:
true - Purpose: Exclude XAML source when compiled XBF exists
AppxExcludeXbfFromSdkPayloadWhenXamlIsPresent
- Type: Boolean
- Default:
true - Purpose: Exclude XBF when XAML source is present
Streaming & Content Groups
AppxStreamableMainPackage
- Type: Boolean
- Default:
true - Purpose: Mark main package as streamable during Store installation
- Benefit: Allows app to start while still installing
AppxStreamableResourcePackages
- Type: Boolean
- Default:
false - Purpose: Mark resource packages as streamable
ConvertSourceAppxContentGroupMap
- Type: Boolean
- Default:
false - Purpose: Convert source content group map to target format
Testing & Layout Preparation
AppxTestLayoutEnabled
- Type: Boolean
- Default:
true - Purpose: Create test layout for F5 debugging
- Benefit: Enables live debugging of packaged app
AppxUseResourceIndexerApi
- Type: Boolean
- Default:
true - Purpose: Use modern Resource Indexer API for PRI processing
_GenerateMsixPackage
- Type: Boolean (internal)
- Default: Computed from
GenerateAppxPackageOnBuild,PublishAppxPackage,WindowsPackageType - Purpose: Internal flag controlling package generation
Hashing & Extensions
AppxDefaultHashAlgorithmId
- Type: String
- Default:
sha256 - Possible Values:
sha1,sha256,sha384,sha512 - Purpose: Default hash algorithm for package integrity
AppxHashAlgorithmId
- Type: String
- Default:
$(AppxPackageSigningTimestampDigestAlgorithm)or$(AppxDefaultHashAlgorithmId) - Purpose: Hash algorithm for package creation
AppxPackageExtension
- Type: String
- Default:
.msix(v10.0.17200+) or.appx(older) - Purpose: File extension for packages
AppxBundleExtension
- Type: String
- Default:
.msixbundleor.appxbundle - Purpose: File extension for bundles
AppxSymbolPackageExtension
- Type: String
- Default:
.appxsym - Purpose: File extension for symbol packages
Platform & Version
TargetPlatformVersion
- Type: Version string
- Default: (from project SDK)
- Typical Values:
10.0.19041.0,10.0.22621.0 - Purpose: Target Windows platform version
TargetPlatformMinVersion
- Type: Version string
- Default:
$(TargetPlatformVersion) - Purpose: Minimum supported Windows platform version
TargetPlatformIdentifier
- Type: String
- Default: Detected from project type
- Possible Values:
Windows,UAP - Purpose: Platform identifier for manifest
SDKIdentifier
- Type: String
- Default:
UAP - Purpose: SDK identifier for resource qualifiers
SDKVersion
- Type: String
- Default:
10.0 - Purpose: SDK version for manifest
MSBuild Tooling Paths
AppxMSBuildToolsPath
- Type: Path
- Default:
$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\AppxPackage\ - Purpose: Location of AppxPackage build tools
MakeAppxExeFullPath
- Type: File path
- Default: Auto-discovered
- Purpose: Path to makeappx.exe tool
- Note: Usually auto-discovered; override only if needed
SignAppxPackageExeFullPath
- Type: File path
- Default: Auto-discovered
- Purpose: Path to signtool.exe for package signing
MsixTaskAssemblyLocation
- Type: Path
- Default: Auto-resolved based on runtime
- Purpose: Location of MSIX build task assembly (net6.0 or net472)
Properties by Category
Packaging Properties
Control basic package creation and output:
WindowsPackageType: Package type (MSIX, Sparse, None)AppxPackage: Enable/disable package generationAppxPackageDir: Output directory for packagesAppxPackageDirName: Output folder nameLayoutDir: Layout directory before packagingGenerateAppxPackageOnBuild: Auto-generate on buildPublishAppxPackage: Generate on publishGenerateLibraryLayout: Generate layout for library projects
Signing & Security Properties
Manage code signing and certificates:
AppxPackageSigningEnabled: Enable package signingPackageCertificateKeyFile: PFX certificate pathPackageCertificatePassword: Certificate passwordPackageCertificateThumbprint: Certificate thumbprintEnableSigningChecks: Validate signing configurationAppxPackageSigningTimestampServerUrl: Timestamp serverGenerateTemporaryStoreCertificate: Auto-generate temp certificateAzureCodeSigningEnabled: Use Azure Code SigningAzureKeyVaultEnabled: Use Azure Key VaultAzureCodeSigningEndpoint: Azure endpointSkipPublisherNameValidation: Skip publisher validation
Bundle Properties
Control app bundle creation:
AppxBundle: Enable bundle generation (Always/Auto)UapAppxPackageBuildMode: Packaging mode (Store/Sideload/Both)BuildAppxUploadPackageForUap: Generate Store upload packageBuildAppxSideloadPackageForUap: Generate sideload packageAppxPackageUploadDir: Upload package output directoryAppxBundleExtension: Bundle file extensionAppxBundleAutoResourcePackageQualifiers: Resource splitting criteria
Resource & Localization (PRI) Properties
Manage resource index generation:
AppxGeneratePriEnabled: Enable PRI generationProjectPriFileName: Output PRI filenameProjectPriFullPath: Full PRI pathAppxDefaultResourceQualifierUAP_Language: Default languageAppxDefaultResourceQualifierUAP_Scale: Default scale (DPI)AppxBundleAutoResourcePackageQualifiers: Resource qualifiers for splittingEnableDefaultPriItems: Auto-include resource filesShouldComputeInputPris: Merge referenced PRI filesGenerateLibraryLayout: Generate library layout for resources
Layout & Deployment Properties
Control package layout and file structure:
LayoutDir: Main layout directoryAppxLayoutEnabled: Enable layout filesAppxLayoutFileName: Layout template filenameUseAppxLayout: Apply layout templateAppxLayoutDir: Layout processing directoryGenerateLibraryLayout: Library layout generationRemoveNonLayoutFiles: Remove non-layout filesIncludeLayoutFilesInPackage: Include layout files in package
Payload & File Management Properties
Control what files go into the package:
AppxSkipUnchangedFiles: Skip unchanged files (faster)AppxUseHardlinksIfPossible: Use hardlinks (faster)AppxUseHardlinksForNugetIfPossible: Hardlinks for NuGetAppxRemoveRedundantCopyLocalItems: Remove duplicatesIncludeDocumentationFilesInAppxPackage: Include XML docsAppxFilterOutUnusedLanguagesResourceFileMaps: Exclude unused languagesAppxExcludeXamlFromLibraryLayoutsWhenXbfIsPresent: Prefer XBF over XAMLAppxExcludeXbfFromSdkPayloadWhenXamlIsPresent: Prefer XAML over XBF
Symbol & Debugging Properties
Control symbol package generation:
AppxSymbolPackageEnabled: Generate symbol packageAppxPackageIncludePrivateSymbols: Include private symbolsAppxSymbolIntermediateDir: Symbol processing directoryAppxSymbolPackageExtension: Symbol package extension
Manifest & Validation Properties
Control manifest generation and validation:
AppxStrictManifestValidationEnabled: Strict validationAppxPackageValidationEnabled: Package validationDisableAppxManifestItemPackageContentValidation: Skip content validationAppxManifestFileName: Manifest output filenameFinalAppxManifestName: Final manifest path
Feature Flags & Advanced Properties
Lower-level control flags:
AppxStreamableMainPackage: Streamable main packageAppxStreamableResourcePackages: Streamable resource packagesAppxTestLayoutEnabled: Create test layout for F5AppxUseResourceIndexerApi: Use Resource Indexer APIAppxGetPackagePropertiesEnabled: Get package propertiesAppxGeneratePrisForPortableLibrariesEnabled: PRI for portable libsAppxGeneratePackageRecipeEnabled: Generate recipe filesBuildOptionalProjects: Build optional dependency projectsPackageOptionalProjectsInIdeBuilds: IDE-specific optional builds_GenerateMsixPackage: Internal: force package generation
Important Targets
Developers may need to hook into these key targets:
Build Chain Targets
PrepareMsixPackage
- Purpose: Prepares the package layout for building/debugging
- When: Before package generation
- Dependencies: Compiles app, copies files, generates manifests
- Hook Point: Use
BeforeTargets="PrepareMsixPackage"to run custom tasks before prep - Typical Use: Modify files before packaging
GenerateMsixPackage
- Purpose: Main target that orchestrates complete package generation
- Condition: Runs when
GenerateAppxPackageOnBuild=trueorPublishAppxPackage=true - Outputs: .msix/.appx files, symbol packages, recipes
- Dependencies: PrepareMsixPackage, manifest generation, payload computation
- Hook Point:
AfterTargets="GenerateMsixPackage"for post-processing
_GenerateAppxPackageFile
- Purpose: Create the actual .msix/.appx package file using MakeAppx
- Input: Manifest, payload files, file map
- Output: Final package file (e.g.,
MyApp.msix) - Note: Uses
AppxPackageFileMapto list all contents
_GenerateAppxUploadPackageFile
- Purpose: Create Store upload package (.msixupload)
- Condition:
BuildAppxUploadPackageForUap==true - Special: Excludes .pdb files, optimized for Store
- Contains: Main .msix + symbol package
_CreateAppStoreContainerForUAP
- Purpose: Create final .msixupload container for Store submission
- Input: Upload package + symbol package
- Output: Single .msixupload file with both
- Note: Only for Store builds
Manifest & Recipe Targets
_GenerateAppxManifest
- Purpose: Generate AppxManifest.xml from Package.appxmanifest and build info
- Handles: Capability injection, SDK reference adding, target device family setup
- Output:
FinalAppxManifestName(usually in output directory) - Key Task:
WinAppSdkGenerateAppxManifest
_GenerateAppxPackageRecipe
- Purpose: Create .appxrecipe file documenting package contents
- Purpose: Debug/recipe file tracking all files in package
- Output:
.build.appxrecipefile - Usage: Used by deployment tools
_GenerateAppxUploadPackageRecipe
- Purpose: Recipe file for upload package (Store)
- Special: Excludes .pdb files
- Output:
AppxUploadPackageRecipe
Resource & Symbol Targets
GenerateProjectPriFile
- Purpose: Generate project resource index (resources.pri or project-specific .pri)
- Condition:
AppxGeneratePriEnabled==true - Inputs: .xaml, .resw, and other resource files
- Outputs:
.prifile in output directory - Configuration: Controlled by PRI configuration files
_GenerateAppxSymbolPackage
- Purpose: Create separate symbol package (.appxsym)
- Condition:
AppxSymbolPackageEnabled==true - Contents: Symbol files (.pdb) from the build
- Distribution: Uploaded separately to Microsoft Store
- Benefit: Enables Store to provide crash data to developers
_GenerateAppxUploadSymbolPackage
- Purpose: Symbol package for upload/Store scenario
- Input: Upload package payload symbols
- Output:
.appxsymin upload artifacts directory
Layout & Deployment Targets
_ReadAppxLayout / _FindAppxLayoutFile
- Purpose: Read and process PackageLayout files
- Condition:
AppxLayoutEnabled==true - Input:
.packagelayoutXML files - Usage: Advanced deployment and layout control
_CreateTestLayout
- Purpose: Create test deployment directory for F5 debugging
- Location: Usually
bin\Debug\AppX\ - Benefit: Allows local testing without full packaging
- Condition: Automatic for development builds
Validation Targets
_ValidateWindowsPackageType
- Purpose: Validate that WindowsPackageType is correctly configured
- Checks: Valid values, configuration consistency
- Error Conditions:
- WindowsPackageType=None + GenerateAppxPackageOnBuild=true
- WindowsPackageType=None + AppxManifest exists
- Hook: Part of PrepareForBuild chain
_ValidateConfiguration
- Purpose: Validate project build configuration
- Checks: Platform version, language, platform identifier
- Task:
WinAppSdkValidateConfiguration
_ValidateSigningCertificate
- Purpose: Validate signing certificate exists and is valid
- Condition:
AppxPackage==trueand signing enabled - Checks: Certificate thumbprint, password, publisher name
- Error: If certificate missing or invalid
MsixCheckForInvalidCustomBeforeMicrosoftCommonTargets
- Purpose: Ensure MSIX props were imported in correct chain
- Error: If custom build targets bypass MSIX props
- Note: Safety check for build system integrity
Packaging Mode Targets
_ValidateAzureCodeSigningVersion
- Purpose: Check Azure Code Signing configuration versions
- Condition:
AzureCodeSigningEnabled==true - Validates: SDK and tool versions compatibility
_ValidateAzureKeyVaultVersion
- Purpose: Check Azure Key Vault configuration versions
- Condition:
AzureKeyVaultEnabled==true
_ValidatePublisherName
- Purpose: Validate publisher name matches certificate
- Condition: Store build with signing enabled
- Prevents: Store submission with mismatched publisher
Usage Examples
Example 1: Basic MSIX Packaging
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
<!-- Signing with certificate -->
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
<PackageCertificateKeyFile>$(ProjectDir)SigningCert.pfx</PackageCertificateKeyFile>
<PackageCertificatePassword>$(CertPassword)</PackageCertificatePassword>
</PropertyGroup>Example 2: Store Packaging (Production Build)
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<!-- Store packaging options -->
<UapAppxPackageBuildMode>StoreAndSideload</UapAppxPackageBuildMode>
<PublishAppxPackage>true</PublishAppxPackage>
<!-- Signing for Store -->
<PackageCertificateKeyFile>$(ProjectDir)StoreCert.pfx</PackageCertificateKeyFile>
<PackageCertificatePassword>$(StoreCertPassword)</PackageCertificatePassword>
<!-- Symbols for crash reporting -->
<AppxSymbolPackageEnabled>true</AppxSymbolPackageEnabled>
<AppxPackageIncludePrivateSymbols>true</AppxPackageIncludePrivateSymbols>
</PropertyGroup>Example 3: Bundle with Resources
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<!-- Bundle settings -->
<AppxBundle>Always</AppxBundle>
<AppxBundleAutoResourcePackageQualifiers>Language|Scale</AppxBundleAutoResourcePackageQualifiers>
<!-- Resource generation -->
<AppxGeneratePriEnabled>true</AppxGeneratePriEnabled>
<ProjectPriFileName>resources.pri</ProjectPriFileName>
<AppxFilterOutUnusedLanguagesResourceFileMaps>true</AppxFilterOutUnusedLanguagesResourceFileMaps>
</PropertyGroup>Example 4: Custom Output Directory
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
<!-- Custom paths -->
<AppxPackageDir>$(SolutionDir)PackageOutput\$(Configuration)\$(Platform)\</AppxPackageDir>
<LayoutDir>$(IntermediateOutputPath)PackageLayout\</LayoutDir>
</PropertyGroup>Example 5: Azure Code Signing
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
<!-- Azure Code Signing -->
<AzureCodeSigningEndpoint>https://eus.codesigning.azure.net</AzureCodeSigningEndpoint>
<AzureCodeSigningAccountName>myaccount</AzureCodeSigningAccountName>
<AzureCodeSigningCertificateProfileName>my-profile</AzureCodeSigningCertificateProfileName>
<AzureCodeSigningDlibVersion>0.2.0.25</AzureCodeSigningDlibVersion>
<!-- Skip publisher name validation with Azure -->
<SkipPublisherNameValidation>true</SkipPublisherNameValidation>
</PropertyGroup>Example 6: Azure Key Vault Integration
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
<!-- Azure Key Vault -->
<AzureKeyVaultUrl>https://myvault.vault.azure.net/</AzureKeyVaultUrl>
<AzureKeyVaultCertificateId>certificates/my-cert/</AzureKeyVaultCertificateId>
<SkipPublisherNameValidation>true</SkipPublisherNameValidation>
</PropertyGroup>Example 7: Debug Build (No Packaging)
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<!-- Package info is prepared but not generated -->
<GenerateAppxPackageOnBuild>false</GenerateAppxPackageOnBuild>
<!-- Just prepare layout for F5 debugging -->
<AppxTestLayoutEnabled>true</AppxTestLayoutEnabled>
</PropertyGroup>Example 8: CI/CD Multi-Platform Build
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<!-- Always generate in CI -->
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
<!-- CI output -->
<AppxPackageDir>$(BuildArtifactsStagingDirectory)\packages\$(Platform)\$(Configuration)\</AppxPackageDir>
<!-- Signing in CI environment -->
<PackageCertificateKeyFile>$(Build_SourcesDirectory)\build\cert.pfx</PackageCertificateKeyFile>
<PackageCertificatePassword>$(CERT_PASSWORD)</PackageCertificatePassword>
</PropertyGroup>Example 9: Sparse Package (Multi-Project Scenario)
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>Sparse</WindowsPackageType>
<!-- Sparse packages are always generated -->
<!-- They provide identity but minimal content -->
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
</PropertyGroup>Example 10: Conditional Packaging Based on Configuration
<PropertyGroup>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<!-- Release: Generate and sign for Store -->
<UapAppxPackageBuildMode>StoreAndSideload</UapAppxPackageBuildMode>
<PublishAppxPackage>true</PublishAppxPackage>
<PackageCertificateKeyFile>$(ProjectDir)store_cert.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<!-- Debug: Just prepare layout -->
<GenerateAppxPackageOnBuild>false</GenerateAppxPackageOnBuild>
<AppxTestLayoutEnabled>true</AppxTestLayoutEnabled>
</PropertyGroup>Common Property Combinations
For Local Development
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<AppxTestLayoutEnabled>true</AppxTestLayoutEnabled>
<AppxGeneratePriEnabled>true</AppxGeneratePriEnabled>For Store Submission
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<UapAppxPackageBuildMode>StoreAndSideload</UapAppxPackageBuildMode>
<PublishAppxPackage>true</PublishAppxPackage>
<AppxSymbolPackageEnabled>true</AppxSymbolPackageEnabled>
<PackageCertificateKeyFile>...</PackageCertificateKeyFile>For Enterprise Sideload Distribution
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>MSIX</WindowsPackageType>
<BuildAppxSideloadPackageForUap>true</BuildAppxSideloadPackageForUap>
<BuildAppxUploadPackageForUap>false</BuildAppxUploadPackageForUap>
<PackageCertificateKeyFile>...</PackageCertificateKeyFile>Troubleshooting Properties
If you encounter build errors, check these properties:
- "EnableMsixTooling not set" → Set
EnableMsixTooling=true - "Package.appxmanifest not found" → Create manifest or set
WindowsPackageType=None - "Certificate validation failed" → Verify
PackageCertificateKeyFileandPackageCertificatePassword - "Publisher name mismatch" → Ensure manifest publisher matches certificate subject
- "Resource PRI generation failed" → Check
AppxGeneratePriEnabledand resource file locations - "MSBuild props not imported correctly" → Verify
CustomBeforeMicrosoftCommonTargetschain
Related Files & Concepts
- Package.appxmanifest: Application manifest defining identity, capabilities
- .appxbundle/.msixbundle: Multi-platform bundles for distribution
- .appxsym/.msixsym: Debug symbol packages
- .appxrecipe/.build.appxrecipe: Build recipe tracking package contents
- resources.pri: Package Resource Index for localization
- .packagelayout: Layout template for advanced scenarios
- AppxContentGroupMap.xml: Content grouping for streaming install
SDK & Tool Requirements
This package requires:
- MSBuild 16.0 or later
- Windows SDK Build Tools (auto-installed with Visual Studio)
- For signing: Windows SDK or SignTool.exe
- For creating packages: MakeAppx.exe
- For signing packages: SignTool.exe
Compatible with:
- Visual Studio 2019 and later
- .NET Framework 4.7.2+
- .NET 5.0+
- C++/CX and C++/WinRT
- UWP and modern desktop apps