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