winget-cli icon indicating copy to clipboard operation
winget-cli copied to clipboard

Enhancements to list command

Open denelon opened this issue 3 years ago • 5 comments

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.

The first enhancement is adding the values for "Available" and "Source" for every package in configured sources rather that just packages with upgrades available.

The second enhancement is reducing the set of packages to the source specified when the source is passed as an argument to the list command.

The third enhancement is adding an argument to provide the list of Apps with no matching package in configured sources.

The fourth enhancement is enabling a sort behavior.

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:

  • #1488

Note: Users will be able to see if packages are available from individual sources by specifying the source as an argument to the list command.

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.

denelon avatar Jun 11 '21 22:06 denelon

  • https://github.com/microsoft/winget-cli/pull/1156

denelon avatar Jun 11 '21 22:06 denelon

the first configured source should be displayed.

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).

jedieaston avatar Jun 15 '21 14:06 jedieaston

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.

jdhitsolutions avatar Aug 30 '21 17:08 jdhitsolutions

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.

denelon avatar Aug 30 '21 20:08 denelon

Is it possible to add issue #1653 to the list of enhancements. I would greatly appreciate this.

pluto-dev avatar Mar 11 '22 20:03 pluto-dev

I see that there are multiple issues about winget list --source <source> not filtering the results by <source>. All of these issues were closed as duplicates of the current issue, but meanwhile the problem remains.

Is there anyone working on an actual fix?

ackalker avatar Apr 08 '23 11:04 ackalker

Is there anyone working on an actual fix?

@ackalker: Please add your thumbs up (👍) to this issue so that it can be prioritized.

ItzLevvie avatar Apr 08 '23 13:04 ItzLevvie

Although it's not perfect, I have created a function Get-WingetLogs to parse and query the winget logs. It allows searching the logs by string or date boundaries. It also allows highlighting local system paths to make the log messages easier to read.

mavaddat avatar Jun 04 '23 17:06 mavaddat

[Policy] Command-List

Trenly avatar Jun 16 '23 16:06 Trenly

To sort the winget list output I wrote 2 small scripts for powershell.

This one-liner will sort the output alphabetically. This will overwrite the variable $wg if defined. To prevent this use a script block: The call operator & executes the following script block {...} which prevents the variable $wg to be persistent. If the output includes progress bars just rerun the command.

$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 winget list and return a table you can sort as you wish. For sorting use the command Sort-Object as shown in the last two lines.

# 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

klezm avatar Jun 28 '23 14:06 klezm

After 2 years this still isn't solved.

Limyx826 avatar Jul 22 '23 17:07 Limyx826

I see that there are multiple issues about winget list --source <source> not filtering the results by <source>. All of these issues were closed as duplicates of the current issue, but meanwhile the problem remains.

Is there anyone working on an actual fix?

I temporarily use winget list | Select-String "winget" to filter.

GNITOAHC avatar Feb 23 '24 16:02 GNITOAHC

I see that there are multiple issues about winget list --source <source> not filtering the results by <source>. All of these issues were closed as duplicates of the current issue, but meanwhile the problem remains. Is there anyone working on an actual fix?

I temporarily use winget list | Select-String "winget" to filter.

Have you tried using the WinGet PowerShell module? Get-WinGetPackage is the equivalent command for winget list. Since many comments mention sorting as well, you can pipe its output to Sort-Object.

Get-WinGetPackage | Where-Object {($_.Source -eq 'winget')} | Sort-Object Name

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

mdanish-kh avatar Feb 23 '24 19:02 mdanish-kh

That would be quite useful to see which of my installed apps have a corresponding winget manifest and get recognized by winget properly.

CanePlayz avatar Feb 23 '24 23:02 CanePlayz