winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4fbbf0e0221281796e401ccdf97a19cc2ef26d1d
parent aca2fc3d23687ccfebc3e648a3cff1d1a553b9fa
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Fri, 28 Mar 2025 10:18:51 -0700

More graceful MSIX enumeration failure handling (#5329)

Fixes #5318
Mitigates many other issues getting 0x80070490 from installed package
enumeration

## Change
Check for `IPackageManager9` before using it to prevent an AV on older
Windows versions.

Attempt to `FindPackagesForUserWithPackageTypes` with fewer types if it
fails with `E_NOT_SET`. While this is an OS issue, enumerating fewer (or
no) packages is generally better than an error that completely blocks
usage.
Diffstat:
Msrc/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp | 40++++++++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp b/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp @@ -68,14 +68,50 @@ namespace AppInstaller::Repository::Microsoft IIterable<Package> packages; PackageManager packageManager; + if (scope == Manifest::ScopeEnum::Machine) { - packages = packageManager.FindProvisionedPackages(); + // May not be present on our oldest supported systems; simply ignore for the time being. + IPackageManager9 packageManager9 = packageManager.try_as<IPackageManager9>(); + if (packageManager9) + { + packages = packageManager.FindProvisionedPackages(); + } + else + { + AICLI_LOG(Repo, Warning, << "FindProvisionedPackages is not available on this version of Windows"); + } } else { // TODO: Consider if Optional packages should also be enumerated - packages = packageManager.FindPackagesForUserWithPackageTypes({}, PackageTypes::Main | PackageTypes::Framework); + for (PackageTypes types : { PackageTypes::Main | PackageTypes::Framework, PackageTypes::Main, PackageTypes::Framework }) + { + try + { + packages = packageManager.FindPackagesForUserWithPackageTypes({}, types); + break; + } + catch (const winrt::hresult_error& hre) + { + if (hre.code() == E_NOT_SET) + { + // This OS issue occurs frequently enough that we will attempt to work around it by enumerating progressively fewer packages + AICLI_LOG(Repo, Warning, << "FindPackagesForUserWithPackageTypes returned E_NOT_SET for types: " << ToIntegral(types)); + } + else + { + throw; + } + } + } + } + + // Failed to retrieve even an empty package list; make sure that these cases have a log to indicate why. + if (!packages) + { + AICLI_LOG(Repo, Warning, << "MSIX package list not populated"); + return; } // Reuse the same manifest object, as we will be setting the same values every time.