Windows developers have long looked at Linux’s surfeit of package managers with envy. Having a simple command line tool like apt or rpm that would install an application and all its prerequisites makes installing a toolchain easy; all you need is a script that chains together a list of tools. Press return, and you’re ready to go.
That’s never been the case in Microsoft environments, at least not until the Azure CLI and ARM templates. But they’re only for the cloud or for Azure Arc managed systems. They work at a higher level than tools that install an editor, a utility, or a compiler, delivering complete infrastructures. Windows users have had the option of the third-party Chocolatey, building on PowerShell and working with Windows’ native installers, but it means either buying into the Chocolatey ecosystem as an organization or going out of your way to find and install the free desktop client.
Introducing winget
There’s definitely strong demand for a command line-driven package installer in Windows, and Microsoft has finally noticed. In 2020 it announced Windows Package Manager and winget, a package manager that’s being built-in to the Windows App Installer tools. Currently available to Windows Insiders in a preview release of App Installer, winget is also downloadable from GitHub for Windows 10 Version 1709 and later. Alternatively, you can build it from the project source code using Visual Studio 2019 with its desktop development tools for .NET, C++, and UWP. There’s even a separate Insiders program with its own mailing list.
Winget is the first iteration of a built-in package manager for Windows, closely related to various open source alternatives, especially AppGet. It is being built in public on GitHub. It has a similar architecture to most package managers, using application manifests to describe applications and their requirements, with a central managed repository for manifests, each of which links to download sites for application installers.
Once installed, winget behaves like any other command line tool, and can be accessed from either the Windows command line or from PowerShell. It has a built-in search function that can find a specific package or display the entire list of available packages. To get the complete list of packages type winget search
. If you want a local catalog, pipe the output to a file to get a text file with all 1,350 current packages.
Running the winget client
Installing an app from the repository is relatively simple. All you need to do is find the name of the application using search, then run winget install
. You can use a query as part of the install instead of a full package name; additional options allow you to choose specific versions (the default is to install the latest release), how the installer runs, and even where the file should be installed. It’s a quick process, and as apps are installed using standard Windows installers, they can be uninstalled using familiar Windows settings.
You don’t need to run winget as an administrator since it wraps existing installers. So if an application needs administrative privileges, it will use the standard Windows account elevation dialog to request permissions. It’s best to run it as a standard user to get these prompts, as you can cancel installs that might load software you don’t want to run. If you run winget as an administrator, it will install all the files with administrator privileges.
Building winget packages
At the heart of a winget package is an application manifest. This is where developers describe what’s needed for their application to run, using a YAML document. Microsoft provides a full spec for the YAML in its GitHub repository. This simplifies constructing a basic manifest. You need a publisher, an app name, a version, and license details. These are followed by the installer type and a URI for the installer. Next, provide a list of the architectures your app supports and a SHA256 hash to validate the installer when downloaded.
A full manifest has a lot more content, supporting everything from a minimum OS version to a set of search tags that can help find your app. Future releases will allow you to set up multiple installers, ensuring that prerequisites are installed along with your code, with winget executing each installer in order. However, the current preview only supports a single installer.
It’s unclear how future versions of winget will handle multiple installs where apps are already in place. It’s likely that it will be capable of responding to error messages from supported installers, and it should be capable of automatically managing upgrades to new releases as well as fresh installs, skipping over an installer where an app is already on the target PC. For now, if you want to install multiple items, it’s best to construct a script that wraps several winget calls so that tools are installed in the correct order.
Manifests are automatically validated when submitted to the winget GitHub package repository. You can use the validate command in the winget CLI tool to test a manifest before submission. Once tested, you will add your package to a local fork of the repository, using a defined directory format. Once your fork has been set up, use git commands to commit and push your changes to the GitHub repository, finally using a pull request to submit your package manifest to Microsoft. Microsoft will use the GitHub code review process to process your pull request, initially using automatic validation via Azure DevOps tools, with a final human check before it is added to the winget repository and can be downloaded by users.
Working with winget repositories
Currently Microsoft runs the only winget repository. That makes sense during development, but as it shifts into production there’s going to be demand for private repositories as well as third-party support, for example working with existing services such as Chocolatey and providing a way to authenticate against its commercial repositories. A statement in the winget documentation notes that Microsoft is discussing API-based access to other repositories and other installer tools, which should allow the rapid development of a rich package ecosystem of free and paid tools.
By setting up a private repository with tested and approved builds of development tools, a development team can standardize on a single toolchain and a single source of tools. That way everyone will be using the same release of an editor or the same linter, reducing the risk of confusion or failed builds that have been tested on different compilers or using different linkers.
The current builds of winget include some experimental features that can be enabled via its settings command, adding JSON flags to the winget configuration file that’s opened when you call winget settings
. These include options to update and uninstall applications (making it much more like a Linux package manager) and support for working with the Microsoft Store. Currently, you can't access the entire store, only a curated set of utilities.
It’s an example of the type of third-party repository support you can expect from winget—a targeted list of tools that are intended for a limited audience. Don’t expect it to replace the Windows Store any time soon; with the upcoming release of Windows 10X, the store will remain Microsoft’s preferred route for delivering consumer applications to user PCs.
With winget, Microsoft promises to solve many of the issues of targeted software delivery to developers or power users. Winget is a flexible and simple tool. It's easy to build into setup scripts, can quickly deploy entire toolchains as part of an installation image, or support adding consistent tools to a BYOD deployment. It’s worth looking at now, especially if you use any of the more than 1,300 tools currently in the manifest and want to automate setting up your next PC.