Skip to content
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

Add ability to list installed packages by --installer-type with winget list #4003

Open
o-l-a-v opened this issue Dec 20, 2023 · 2 comments
Open
Labels
Command-List Issue related to WinGet List Issue-Feature This is a feature request for the Windows Package Manager client.

Comments

@o-l-a-v
Copy link

o-l-a-v commented Dec 20, 2023

Description of the new feature / enhancement

Just now I wondered what portable packages I've installed with Winget, and found that winget list doesn't really have such filtering capabilities.

Here's the current options with winget list:

Here's the supported installer types:

Here's an example portable package:

Proposed technical implementation details

Add option to specify --installer-type with winget list.

@o-l-a-v o-l-a-v added the Issue-Feature This is a feature request for the Windows Package Manager client. label Dec 20, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Triage Issue need to be triaged label Dec 20, 2023
@mdanish-kh
Copy link
Contributor

Referencing a related issue:

@microsoft-github-policy-service microsoft-github-policy-service bot added the Command-List Issue related to WinGet List label Dec 20, 2023
@denelon denelon removed the Needs-Triage Issue need to be triaged label Dec 20, 2023
@jcrben
Copy link

jcrben commented Oct 14, 2024

Here's a powershell script which takes a stab this, with a bunch of help from github copilot:

# Check if the Microsoft.WinGet.Client module is installed, and install it if not
if (-not (Get-Module -ListAvailable -Name Microsoft.WinGet.Client)) {
    Write-Host "Microsoft.WinGet.Client module not found. Installing..."
    Install-Module -Name Microsoft.WinGet.Client -Scope CurrentUser -Force -AllowClobber
}

Import-Module Microsoft.WinGet.Client

# Function to get the installer type of a package
function Get-InstallerType {
    param (
        [string]$packageId
    )
    # Run the winget show command and capture the output
    $output = winget show $packageId
    # Parse the output to find the installer type
    $installerType = $output | Select-String -Pattern "Installer type" | ForEach-Object {
        $_ -replace "Installer type\s*:\s*", ""
    }
    return $installerType
}

# Function to get information about non-standard IDs from the registry
function Get-NonStandardPackageInfo {
    param (
        [string]$packageId
    )

    $installerType = "Unknown"
    # Extract the unique identifier at the end of the packageId
    if ($packageId -match 'ARP\\Machine\\X64\\{(.+?)}') {
        $uniqueId = $matches[1]
    } elseif ($packageId -match 'ARP\\Machine\\X86\\(.+?)') {
        $uniqueId = $matches[1]
    } else {
        $uniqueId = $packageId -replace '.*\\', ''
    }

    # Add braces if the unique identifier is a GUID
    if ($uniqueId -match '^[0-9a-fA-F-]{36}$') {
        $uniqueId = "{$uniqueId}"
    }

    $registryPaths = @(
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$uniqueId",
        "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$uniqueId",
        "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\$uniqueId"
    )

    foreach ($registryPath in $registryPaths) {
        try {
            $packageInfo = Get-ItemProperty -Path $registryPath -ErrorAction Stop
            if ($packageInfo) {
                $installerType = "MSI"  # Default to MSI for ARP entries, adjust as needed
                break
            }
        } catch {
            Write-Host "Registry path not found: $registryPath"
        }
    }

    return $installerType
}

# Function to get information about MSIX packages from the registry
function Get-MSIXPackageInfo {
    param (
        [string]$packageId
    )

    $installerType = "Unknown"
    $uniqueId = $packageId -replace 'MSIX\\', ''

    $registryPath = "HKLM:\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages\$uniqueId"

    try {
        $packageInfo = Get-ItemProperty -Path $registryPath -ErrorAction Stop
        if ($packageInfo) {
            $installerType = "MSIX"
        }
    } catch {
        Write-Host "Registry path not found: $registryPath"
    }

    return $installerType
}

# Get the list of installed packages
$installedPackages = Get-WinGetPackage

# Loop through each installed package
foreach ($package in $installedPackages) {
    Write-Host "Processing package: $($package.Id)"

    # Determine the installer type
    if ($package.Id -match "^ARP") {
        $installerType = Get-NonStandardPackageInfo -packageId $package.Id
    } elseif ($package.Id -match "^MSIX") {
        $installerType = Get-MSIXPackageInfo -packageId $package.Id
    } else {
        try {
            # Get the installer type for the package and trim the result
            $installerType = (Get-InstallerType -packageId $package.Id).Trim()
        } catch {
            # Log the error and set the installer type to "Error"
            Write-Host "Error processing package $($package.Id): $_"
            $installerType = "Error"
        }
    }

    Write-Host "Installer Type: $installerType"

    # Print the package details
    Write-Output "Name: $($package.Name), Id: $($package.Id), Installer Type: $installerType"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Command-List Issue related to WinGet List Issue-Feature This is a feature request for the Windows Package Manager client.
Projects
None yet
Development

No branches or pull requests

4 participants