How to Automate WinGet Manifest Generation with Advanced Installer

Written by Renato Ivanescu · July 11th, 2025 · 5min read

Publishing an application to the Windows Package Manager (WinGet) requires a manifest file that defines essential metadata, installer information, and localization details.

Manually generating this manifest can be repetitive and error-prone, especially during frequent releases.

To streamline this process, you can automate WinGet manifest generation using Advanced Installer and a PowerShell script that runs as part of your build process.

This article walks you through the steps to automatically generate a WinGet manifest as part of your build workflow.

Prerequisite: Install WingetCreate

Before generating manifests, ensure you install the wingetcreate tool on your system.

If it’s not installed, you have a few options. Here are two common installation methods:

  • Via GitHub Release – Download and install the latest version from the winget-create GitHub repository.
  • Via Windows Package Manager – If WinGet is already installed on your system, open PowerShell and run the following command:
winget install wingetcreate

NoteWinGet tool comes pre-installed on Windows 11 and is available for Windows 10 version 1809 and later. If it’s missing, you can install it by downloading the App Installer from the Microsoft Store.

Once wingetcreate is installed, verify if the installation was successful by running:

wingetcreate –version

This command should display the installed version, confirming the tool is ready for use.

Create the PowerShell Script to Generate Manifests

The next step is to create the PowerShell script that generates the WinGet manifest for your application. You will later configure Advanced Installer to run it as a post-build event.

Here’s an example script. You’ll need to edit the values to match your application’s details.

param (
    [string]$OutputDirectory = "C:\Users\R\WinGetDemo"
)
# PACKAGE METADATA - UPDATE THE VALUES BELOW
$packageInfo = @{
    PackageIdentifier = "YourCompany.YourApplication"  
    PackageVersion = "1.0.0"                          
    Publisher = "Your Company"
    Author = "Your Name/Team"
    PackageName = "Your App Name"
    License = "Proprietary"                          
    ShortDescription = "Your app description"
    Copyright = "Copyright © 2025 YourCompany. All rights reserved."
    ReleaseNotesUrl = "https://yourcompany.com/releasenotes"
    PurchaseUrl = "https://yourcompany.com/purchase"
    PackageUrl = "https://yourcompany.com/yourapp"
    InstallerType = "msi"  # "msi", "msix", etc.
    Scope = "machine"      # "machine" or "user"
    InstallLocation = "C:\\Program Files\\Company\\YourApp"   
    UpgradeBehavior = "install"                      
    ReleaseDate = "2025-06-10"  # YYYY-MM-DD
    # MSI-Specific (Only for MSI packages)
    ProductCode = "{YOUR-GUID-HERE}"                 
    UpgradeCode = "{YOUR-UPGRADE-GUID-HERE}"         
    # Installers
    Installers = @(
        @{
            Architecture = "x86"                    
            InstallerUrl = "https://example.com/path/to/x86/installer.msi"
            InstallerSha256 = "x86-hash-here"       # Get via: (Get-FileHash your.msi -Algorithm SHA256).Hash.ToLower()
        },
        @{
            Architecture = "x64"
            InstallerUrl = "https://example.com/path/to/x64/installer.msi"
            InstallerSha256 = "x64-hash-here"       
        }
    )
}
# MANIFEST GENERATION
# Create version directory
$versionDir = Join-Path -Path $OutputDirectory -ChildPath $packageInfo.PackageVersion
if (-not (Test-Path -Path $versionDir)) {
    New-Item -ItemType Directory -Path $versionDir | Out-Null
}
# 1. Version Manifest
$versionManifest = @"
# yaml-language-server: `$schema=https://aka.ms/winget-manifest.version.1.10.0.schema.json
PackageIdentifier: $($packageInfo.PackageIdentifier)
PackageVersion: $($packageInfo.PackageVersion)
DefaultLocale: en-US
ManifestType: version
ManifestVersion: 1.10.0
"@
# 2. Installer Manifest
$installerManifest = @"
# yaml-language-server: `$schema=https://aka.ms/winget-manifest.installer.1.10.0.schema.json
PackageIdentifier: $($packageInfo.PackageIdentifier)
PackageVersion: $($packageInfo.PackageVersion)
InstallerType: $($packageInfo.InstallerType)
Scope: $($packageInfo.Scope)
InstallerSwitches:
  InstallLocation: "$($packageInfo.InstallLocation)"
UpgradeBehavior: $($packageInfo.UpgradeBehavior)
ReleaseDate: "$($packageInfo.ReleaseDate)"
"@
# Add MSI-specific fields if needed
if ($packageInfo.InstallerType -eq "msi") {
    $installerManifest += @"
ProductCode: "$($packageInfo.ProductCode)"
AppsAndFeaturesEntries:
- ProductCode: "$($packageInfo.ProductCode)"
  UpgradeCode: "$($packageInfo.UpgradeCode)"
"@
}
# Add installers section
$installerManifest += @"
Installers:
- Architecture: $($packageInfo.Installers[0].Architecture)
  InstallerUrl: $($packageInfo.Installers[0].InstallerUrl)
  InstallerSha256: $($packageInfo.Installers[0].InstallerSha256)
- Architecture: $($packageInfo.Installers[1].Architecture)
  InstallerUrl: $($packageInfo.Installers[1].InstallerUrl)
  InstallerSha256: $($packageInfo.Installers[1].InstallerSha256)
ManifestType: installer
ManifestVersion: 1.10.0
"@
# 3. Locale Manifest
$localeManifest = @"
# yaml-language-server: `$schema=https://aka.ms/winget-manifest.defaultLocale.1.10.0.schema.json
PackageIdentifier: $($packageInfo.PackageIdentifier)
PackageVersion: $($packageInfo.PackageVersion)
PackageLocale: en-US
Publisher: $($packageInfo.Publisher)
Author: $($packageInfo.Author)
PackageName: $($packageInfo.PackageName)
License: $($packageInfo.License)
ShortDescription: $($packageInfo.ShortDescription)
Copyright: "$($packageInfo.Copyright)"
ReleaseNotesUrl: "$($packageInfo.ReleaseNotesUrl)"
PurchaseUrl: "$($packageInfo.PurchaseUrl)"
"@
# Add optional PackageUrl if defined
if ($packageInfo.PackageUrl) {
    $localeManifest += @"
PackageUrl: "$($packageInfo.PackageUrl)"
"@
}
$localeManifest += @"
ManifestType: defaultLocale
ManifestVersion: 1.10.0
"@
# Save manifests
Set-Content -Path (Join-Path $versionDir "$($packageInfo.PackageIdentifier).yaml") -Value $versionManifest
Set-Content -Path (Join-Path $versionDir "$($packageInfo.PackageIdentifier).installer.yaml") -Value $installerManifest
Set-Content -Path (Join-Path $versionDir "$($packageInfo.PackageIdentifier).locale.en-US.yaml") -Value $localeManifest
# Completion message
Write-Host @"
Successfully created manifests in: $versionDir
- $($packageInfo.PackageIdentifier).yaml
- $($packageInfo.PackageIdentifier).installer.yaml
- $($packageInfo.PackageIdentifier).locale.en-US.yaml
"@

Save this script as generate-winget-manifest.ps1.

Add a Post-Build Event in the Advanced Installer Project

Before automating manifest generation as part of the build process, make sure you’ve already set up a package project in Advanced Installer. You can follow the steps presented in this article.

Once you configure the project in Advanced Installer, follow these steps to create a post-build event:

  • Navigate to the Builds page in Advanced Installer.
  • Switch to the Build Events tab.
  • Click Add Post-Build EventNew.
Add a new Post-Build event in Advanced Installer

The Builds Page is available in the Advanced Installer Professional edition, and you can fully explore it during your 30-day free trial.

Your trial also gives you access to: MSI(X) Editing, Repackaging, Auto-Updates, CI/CD Integration, Digital Signing (Trusted Singing included), And more

Start Free Trial

Configure the Post-Build Event

After creating the event, you will be prompted to configure it.

Since we run a PowerShell script, use the following values for the field:

- Command: powershell.exe

- Arguments:

-NoProfile -ExecutionPolicy Bypass -Command "& {.\generate-winget-manifest.ps1 }"

- Working Dir: Set this to the folder where your script is located. In this example, it’s in the same directory as the .aip project file.

Edit and configure the post-build event

Build the Project and Validate the Manifest

Once the post-build event is configured, build the project. After the build is complete you should see the generated WinGet manifest files in your working directory.

To validate the manifest use:

winget validate <path-to-manifest>

Thus, you’ll ensure the manifest meets the requirements.

To test the installation, run:

winget install --manifest <path-to-manifest>

Video Tutorial

Conclusion

Now you know how to use Advanced Installer to automate the WinGet manifest generation as part of your build process. This streamlines the deployment workflow and saves time when publishing your package to the Windows Package Manager.

Written by
See author's page
Renato Ivanescu

Renato is a technical writer for Advanced Installer and an assistant professor at the University of Craiova. He is currently a PhD. student, and computers and information technology are his areas of interest. He loves innovation and takes on big challenges.

Comments: