Windows remains in the dark ages and doesn't tend to handle installation via package managers, rather it's a libertarian paradise where every application gets to choose how it gets installed and has to provide the infrastructure to do so. The best one can do is create .msi files [[ https://en.wikipedia.org/wiki/Windows_Installer | which are "Windows Installer" packages ]] which //is// technically then handled by a package manager, but (a) those packages are pretty basic and (b) that's then merely packages, no repositories.
To get some of the user friendliness of stuff like #Linux into #Windows, you have to use something else.
== List of Windows package managers ==
| Name | Interface | Source and destination | Available |
| ------- | ----------- | ------ | ---------- |
| [[ https://en.wikipedia.org/wiki/Microsoft_Store | Microsoft Store ]] | GUI | Installs apps per-user from a single central Microsoft-run repository of [[ https://learn.microsoft.com/en-us/windows/msix/package/packaging-uwp-apps | .msix and .appx ]] packages | NT 6.2+ |
| [[ https://en.wikipedia.org/wiki/Windows_Package_Manager | WinGet ]] aka "Windows Package Manager" | CLI | Installs apps from a Microsoft-run repository of .exe and .msi(x) installers or the Microsoft Store (or [[ https://github.com/microsoft/winget-cli-restsource | a custom repo ]] but that seems like a pain in the ass) | NT 10.0+ |
| [[ https://chocolatey.org/ | Chocolatey ]] | CLI | Installs system-wide from an open repository or [[ https://docs.chocolatey.org/en-us/features/host-packages | custom repositories ]] of [[ https://en.wikipedia.org/wiki/NuGet | NuGet ]] packages | NT 6.1+ |
| [[ https://learn.microsoft.com/en-us/powershell/module/packagemanagement/ | PackageManagement ]] | CLI | PowerShell module for NuGet packages that points at the Chocolatey repo by default | PS 5.1+ |
| [[ https://scoop.sh/ | Scoop ]] | CLI | Installs per-user and [[ https://github.com/ScoopInstaller/Scoop/wiki/Dependencies | without shared libraries ]] from packages defined by simple JSON manifest, default repository focused on Free Software and Scoop aims to essentially be a modern (and more `apt`-like) Cygwin | NT 6.1+ via PS 5.1+ |
External comparisons and lists:
* https://github.com/ScoopInstaller/Scoop/wiki/Chocolatey-and-Winget-Comparison
* https://en.wikipedia.org/wiki/List_of_software_package_management_systems#Windows
== Known Issues ==
Because nothing on Windows is ever easy . . .
=== WinGet over SSH ===
You may be like, oh well if there's an official package manager why would I ever use anything else other than for packages that aren't in it? Well the problem is that over some remote sessions like SSH, shit's entirely broken. See [[ https://github.com/microsoft/winget-cli/issues/1474 | winget-cli issue 1474]] for an example which seems to imply SSH just //won't// work, though @keithzg has run into issues [[ https://github.com/microsoft/winget-cli/issues/2434 | along a different line ]]:
```
lang=ini
Do you agree to all the source agreements terms?
[Y] Yes [N] No: Y
Failed when searching source: winget
An unexpected error occurred while executing the command:
0x8a15000f : Data required by the source is missing
# edit 2023-06-14: Same repro, different error message, same solution as below
Failed in attempting to update the source: winget
Failed when searching source; results will not be included: winget
```
Solved with the following, cribbed from [[ https://github.com/microsoft/winget-cli/issues/2434#issuecomment-1229025320 | a comment on an open issue about not being able to bootstrap WinGet automatically]]:
```
lang=powershell, name=Elevated PowerShell session
Invoke-WebRequest 'https://cdn.winget.microsoft.com/cache/source.msix' -OutFile '.\Microsoft.Winget.Source.msix' -UseBasicParsing
Add-AppxPackage -Path 'Microsoft.Winget.Source.msix';
```
I [[https://github.com/microsoft/winget-cli/issues/3153#issuecomment-1507937223|commented on this on a new issue where someone was wondering if WinGet is down]] so hopefully someone will chime in if this is a bad idea.
=== Newly installed stuff isn't in PATH ===
It's very Windows behavior—even opening a new PowerShell session from the CLI won't work. But this (from https://github.com/microsoft/winget-cli/issues/549#issuecomment-1539093267) will:
```
lang=powershell
$Env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine")
```