I saw a tweet recently about winget as a windows package manager and I had to try it out. I’d never used it before, never installed anything with it, so surely it wasn’t going to be particularly useful for me, right? Right?

Wrong.

History of Winget

Package management is one of those things that Linux and Mac users will often roast Windows for. Every major Linux distribution has at least one package manager installed, sometimes two! Mac has brew and macports as popular options for package mangaement that have gained enough traction that, at this point, they may as well just be default options. But Windows has always struggled a bit. The Windows installation workflow was basically “Bing it” – but now we can… winget. Wing it. Get it? Hah.

June 30th, 2020, Microsoft releases their free and open-source package manager, winget, designed for Windows 10 and Windows 11. Boasting many features similar to it’s kin on Linux and Windows, it promised to make package management on Windows easier. If only I’d heard of it before July 28th, 2022.

How does it work?

After seeing that tweet, I immediately opened up Powershell and typed in the update command. winget upgrade --all. Simple as that. It immediately popped up about 2 dozen applications on my machine that had updates available, and then began downloading and installing them one by one. Bizarre, because I didn’t install any of these applications with this tool. Imagine if apt upgrade found other random packages on your machine that had updates available, even if you didn’t install through apt. Wild.

Did application developers have to opt in to this? How did it know where to get the updates? How did it know the updates were safe? Can I set up my own repository of packages to point people to?

Knowing what applications are installed

How did winget know what applications were installed in order to know what to update? I guess Windows has a leg up in this regard because the Programs and Features menu from the control panel has always pretty reasonably been able to tell you what applications are installed, as well as the publisher and the version installed. I didn’t spend a ton of time diving into the exact specifics of how it knows, because I felt reasonably confident that it is probably just enumerating this data.

Knowing what updates are available

Googling around (Sorry Microsoft, even though winget is cool, I still can’t bring myself to use Bing), I found winget-pkgs. This is the open source repository that stores the manifest files used to determine what versions of packages are available. You can dig around the repository and find all sorts of packages in the manifests folder. There are tons of open pull requests (293 at time of writing), and tons more closed pull requests (66,093 at time of writing).

Winget-cli uses this winget-pkgs repository, albeit through some CDN cache layers, and the manifests it contains in order to determine if there are applications you have installed that have updates available. You can see where winget is getting it’s manifest files from by using the winget source list command, shown below.

winget source list

Diving back into the repository, I wanted to understand if the manifests were being generated by the developers or if it relied on third parties. Ultimately it looks like it relies on third parties, and some of these parties have very clearly automated a process to find new versions of packages, generate manifests, and submit them as pull requests. One such example is vedantmgoyal2009 who has authored more than 14,100 pull requests to the repository. Amusing note: I think this profile has so much activity from automation that his Github profile page takes too long to load.

Once a pull request is opened, it looks like it goes through a bunch of automatic validation to make sure that what gets installed is what the manifest is claiming to be. One such example of this is the latest release of Citrix Workspace:

  • the PR was opened by vedant’s automated winget-pkgs update process
  • then wingetbot comments with the status of the pipelines
  • wingetbot runs the pipelines
  • a moderator marks the changes as approved (Whether this is manual or automatic, I can’t quite tell)
  • once the pipeline has finished validating everything, msftbot automatically merges the commit and publishes it.

Finding new packages

So far, everything has been focused on how the update from the original tweet worked. But a good package manager will also have the ability to search for and install new packages. So how does winget stack up against the others? Pretty well, it seems.

To find a new package, winget ships with a command called winget search. You can search for arbitrary keywords and it will return the results for you. Going back to the Citrix Workspace example, I ran winget search citrix and was shown a few options that were available to install.

winget search citrix showing 3 results, 2 from msstore and 1 from winget

I was surprised to see results from msstore in the search results. I guess winget hooks in to Microsoft Store to see what is available for installation from there, as well.

Installing new packages

Having found a package, we should be able to install it without having to leave our terminal. Sure enough, winget delivers again. So let’s install Citrix Workspace and see what happens. winget install citrix

winget install citrix terminal output

Hmm, this looks like it’s defaulting to installing from Microsoft Store. I can’t say I’m particularly surprised by that, since the Microsoft Store options were the first two in the search results. But it’s also not really what I wanted in this case. Instead, I want to install the latest version from winget. I guess I need to be more specific in the command I run. I went ahead and hit ctrl-c to get out of accepting the agreements.

Next, I’ll try to install by the exact ID. winget install Citrix.Workspace.

winget install Citrix.Workspace

This worked as expected, it found the correct version that we saw in the most recently closed pull request from above. Then it automatically started the download and launched the installer. I was a little surprised to see that it didn’t prompt me to confirm that this was what I wanted to install, such as apt-get install does unless passed a special flag -y.

I will note that it did pop up the UAC popup asking me to approve the installation since my terminal wasn’t running as Administrator. This is good, but I hit no in that popup and winget then told me that the package was successfully installed. I sure hope it wasn’t successfully installed if I explicitly hit no…

To see if there was any confirmation when UAC wasn’t in the way, I launched another terminal as Administrator and ran the same command. winget install Citrix.Workspace

winget install Citrix.Workspace

This time it didn’t pop up any UAC prompt, nor did it prompt me in line before launching the installer. In fact, I didn’t see anything happen until the installation was finished. winget told me that installation failed with an exit code of 3010. A quick google suggests that this is effectively reboot required, which I wouldn’t really consider a failure mode.

I checked my start menu and sure enough, Citrix Workspace was installed despite the failure message. So winget install did exactly what it should have done, albeit without as much confirmation as I’d like, and with a strange failure message for an otherwise successful installation.

The only problem? Now I have Citrix Workspace installed. I don’t even know what Citrix Workspace is, and I’d prefer to keep it that way.

Uninstalling packages

Thankfully, winget also provides an uninstallation mechanism, appropriately named winget uninstall. Let’s uninstall Citrix Workspace with winget uninstall Citrix.Workspace.

winget uninstall Citrix.Workspace

Winget launched the uninstaller, not shown here, and I went through the uninstall process as I normally would have through the add/remove programs menu. Whew. I’m glad Citrix Workspace is off my computer. I’m also glad that the uninstaller asked me if I was sure, since winget didn’t care if I was sure or not.

Final thoughts

Overall, I’m pleasantly surprised to learn about winget, and using it isn’t particularly painful. Certainly no more or less painful than apt or brew. I do wish that it had a built in confirmation prompt when installing things from the winget repositories, similar to what it has when installing from the Microsoft Store. It also feels like it has some rough edges, such as the “Installation failed” because the installation succeeded but needed a reboot.

Is there something cool I should know about winget? Something I got wrong in this post? Tweet me and let me know.

It’s funny how apt lost the get and then windows got the get.