-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancements to list command #1155
Comments
Why not the highest version available? If I have multiple sources and one is kept more up-to-date than another, I'd want to see that instead (as a reason people add multiple sources is often because one is more maintained than another). |
This looks like the right place to add instead of opening a new issue. The List parameter needs to have additional logic that only shows me packages installed by Winget. In fact, I think that should be the default. Give me a --all switch to show all possible apps. Although I'm not sure what good it does to see a package like Microsoft.BingWeather_8wekyb3d8bbwe in the List output when winget can't really do anything with it. |
Users can still "uninstall" packages regardless of how they were installed. It's also possible for a user to install a version with the Windows Package Manager, and then upgrade/downgrade it manually. We do have additional complexity to handle when a package is available in more than one source. |
Is it possible to add issue #1653 to the list of enhancements. I would greatly appreciate this. |
I see that there are multiple issues about Is there anyone working on an actual fix? |
Although it's not perfect, I have created a function |
[Policy] Command-List |
To sort the This one-liner will sort the output alphabetically. $wg = winget list; $wg[0..3]; $wg[4..($wg.Length-1)] | Sort-Object
# Or inside a script block
& { $wg = winget list; $wg[0..3]; $wg[4..($wg.Length-1)] | Sort-Object } This will parse the output of # Get the output of winget list
$wgRaw = winget list # -n 15
# Length of longest line
$lengthMax = $wgRaw | ForEach-Object { $_.Length } | measure -Maximum | Select-Object -ExpandProperty Maximum
# Index of the header line
$header_index = $wgRaw.IndexOf(($wgRaw | Where-Object { $_ -match "^-{" + ($lengthMax - 2) + "}" })) - 1
# Remove all lines before the header line (removes progress bars)
$wglist = $wgRaw[$header_index..($wgRaw.Length - 1)]
# $wglist.GetType(); $wglist | ForEach-Object { $_.GetType() } | Get-Unique
# Column names
$col_names = $wglist[0] -split '\s+'
# Column indices (start index of each column)
$ci = ($col_names | ForEach-Object { $wglist[0].IndexOf($_) }) # + $lengthMax
# Column widths
$cw = 0..($ci.Length - 1) | ForEach-Object { $ci[$_ + 1] - $ci[$_] }
# Match blocks of any characters with the lengths given in $cw
$regex = "^" + (($cw[0..($cw.Length - 2)] | ForEach-Object { "(.{$_})" }) -join "") + "(.*)$" # { "(.{" + ($_ - 1) + "})" }) -join " " # Include spaces between columns
# Replacement string with the blocks separated by "|"
$replace = (0..($col_names.Length - 1) | ForEach-Object { '$' + ($_ + 1) + "" }) -join "|"
# Convert fixed length lines into "|" separated lines
$wglist = $wglist | ForEach-Object { $_.PadRight($lengthMax) -replace $regex, $replace }
# Trim whitespaces of all values
$wglist = $wglist | ForEach-Object { $_ -replace " *" + "|" + " *", "|" }
# Parse CSV
$wglist = $wglist[2..($wglist.Length - 1)] | ConvertFrom-Csv -Delimiter "|" -Header $col_names # | ForEach-Object { $_.Trimend() }
# Sort and print as table
# Because of different locales better use $col_names values: $col_names = "Name","Id","Version","Available","Source"
$wglist | Sort-Object -Property @{Expression = $col_names[4]; Descending = $true},$col_names[0] | Format-Table # -GroupBy $col_names[4]
# Filter where Source is winget
# $wglist | Sort-Object -Property $col_names[4],$col_names[0] | Where-Object { $_.Quelle -eq "winget" } | Format-Table Because I had some encoding problems I had to set the encoding in the powershell (see: stackoverflow.com) $OutputEncoding = [System.Text.Encoding]::UTF8 # Sets the encoding for e.g. | and/or communication between programs and/or processes
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 # Sets the encoding for STDOUT and the console/terminal output |
After 2 years this still isn't solved. |
I temporarily use |
Have you tried using the WinGet PowerShell module? Get-WinGetPackage is the equivalent command for
While I understand this issue primarily pertains to achieving these functionalities within the CLI output, I wanted to mention the PowerShell module (since it hasn't been referenced here) as a potential solution that might fulfill someone's needs. Note: Currently the PowerShell module only works on PowerShell 7 MSI |
That would be quite useful to see which of my installed apps have a corresponding winget manifest and get recognized by winget properly. |
@klezm thix for your answer, I can not use external modules in my project and I need to parse Ids from <#
.SYNOPSIS
Extracts the IDs of installed packages using winget.
.DESCRIPTION
The Get-InstalledWingetPackages function retrieves the list of installed packages via winget, processes the output to extract package IDs, and filters out invalid IDs.
.PARAMETER None
This function does not take any parameters.
.EXAMPLE
$installedPackages = Get-InstalledWingetPackages
#> all packages: function Get-InstalledWingetPackages {
$installedPackages = @()
# Get the output of winget list
$wgRaw = winget list --accept-source-agreements --disable-interactivity | Select-Object -Skip 2
# Length of longest line
$lengthMax = $wgRaw | ForEach-Object { $_.Length } | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum
# Index of the header line
$header_index = $wgRaw.IndexOf(($wgRaw | Where-Object { $_ -match "^-{" + ($lengthMax - 2) + "}" })) - 1
# Remove all lines before the header line (removes progress bars)
$wglist = $wgRaw[$header_index..($wgRaw.Length - 1)]
# Column names
$col_names = $wglist[0] -split '\s+'
# Column indices (start index of each column)
$ci = ($col_names | ForEach-Object { $wglist[0].IndexOf($_) })
# Column widths
$cw = 0..($ci.Length - 1) | ForEach-Object { if ($_ -lt $ci.Length - 1) { $ci[$_ + 1] - $ci[$_] } else { $lengthMax - $ci[$_] } }
# Match blocks of any characters with the lengths given in $cw
$regex = "^" + (($cw[0..($cw.Length - 2)] | ForEach-Object { "(.{$_})" }) -join "") + "(.*)$"
# Replacement string with the blocks separated by "|"
$replace = (0..($col_names.Length - 1) | ForEach-Object { '$' + ($_ + 1) + "" }) -join "|"
# Convert fixed length lines into "|" separated lines
$wglist = $wglist | ForEach-Object { $_.PadRight($lengthMax) -replace $regex, $replace }
# Trim whitespaces of all values
$wglist = $wglist | ForEach-Object { $_ -replace " *" + "|" + " *", "|" }
# Parse CSV
$wglist = $wglist[2..($wglist.Length - 1)] | ConvertFrom-Csv -Delimiter "|" -Header $col_names
# Extract Ids
$ids = $wglist | ForEach-Object { $_.Id }
return $ids
}
those in winget ids naming convention (skip for some packages with brackets and numbers (, packages with MSIX\Microsoft.NET.Native.Runtime.2.2_…
MSIX\Microsoft.NET.Native.Runtime.2.2_…
ARP\Machine\X86\{A304E528-86BF-476D-AE…
ARP\Machine\X86\{AFF21875-978B-498C-B6… function Get-InstalledWingetPackages {
$installedPackages = @()
# Get the output of winget list
$wgRaw = winget list --accept-source-agreements --disable-interactivity | Select-Object -Skip 2
# Length of longest line
$lengthMax = $wgRaw | ForEach-Object { $_.Length } | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum
# Index of the header line
$header_index = $wgRaw.IndexOf(($wgRaw | Where-Object { $_ -match "^-{" + ($lengthMax - 2) + "}" })) - 1
# Remove all lines before the header line (removes progress bars)
$wglist = $wgRaw[$header_index..($wgRaw.Length - 1)]
# Column names
$col_names = $wglist[0] -split '\s+'
# Column indices (start index of each column)
$ci = ($col_names | ForEach-Object { $wglist[0].IndexOf($_) })
# Column widths
$cw = 0..($ci.Length - 1) | ForEach-Object { if ($_ -lt $ci.Length - 1) { $ci[$_ + 1] - $ci[$_] } else { $lengthMax - $ci[$_] } }
# Match blocks of any characters with the lengths given in $cw
$regex = "^" + (($cw[0..($cw.Length - 2)] | ForEach-Object { "(.{$_})" }) -join "") + "(.*)$"
# Replacement string with the blocks separated by "|"
$replace = (0..($col_names.Length - 1) | ForEach-Object { '$' + ($_ + 1) + "" }) -join "|"
# Convert fixed length lines into "|" separated lines
$wglist = $wglist | ForEach-Object { $_.PadRight($lengthMax) -replace $regex, $replace }
# Trim whitespaces of all values
$wglist = $wglist | ForEach-Object { $_ -replace " *" + "|" + " *", "|" }
# Parse CSV
$wglist = $wglist[2..($wglist.Length - 1)] | ConvertFrom-Csv -Delimiter "|" -Header $col_names
# Extract Ids and filter out invalid ones
$ids = $wglist | ForEach-Object { if ($_.Id -notmatch '^\{.*\}$' -and $_.Id -notmatch '^ARP\\.*$' -and $_.Id -notmatch '^MSIX\\.*$') { $_.Id } }
return $ids
} |
Description of the new feature/enhancement
The
winget list
command was designed to display all packages installed on a users Windows 10 machine in Add / Remove Programs (ARP). The command would also show which Apps with possible upgrades were available from sources configured in the Windows Package Manager. This specification proposes enhancements to the output provided by the list command.Proposed technical implementation details (optional)
Modify the output behavior for
winget list
to display available version from any source. When a package is available via more than once source, the first configured source should be displayed.Affected by:
Modify the output behavior for
winget list -s <source>
to display only packages available from the specified source.Add a new argument
-u, --unavailable
to the list command to display Apps installed in Windows Apps & Features not matching any configured source.The text was updated successfully, but these errors were encountered: