From 1c00937544e43a3969537de01516f5ca6ac340fa Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Fri, 14 Feb 2025 18:25:01 -0800 Subject: [PATCH 1/9] minor test data consistency --- .../TestCollateral/V1_10ManifestMerged.yaml | 2 +- .../TestCollateral/V1_9ManifestMerged.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml index 7c06202ddf..43dfae3b7e 100644 --- a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml +++ b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_10ManifestMerged.yaml @@ -260,4 +260,4 @@ Installers: ProductCode: '{Bar}' MSStoreProductIdentifier: fakeIdentifier ManifestType: merged -ManifestVersion: 1.7.0 +ManifestVersion: 1.10.0 diff --git a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml index b6efa0343b..5c588770f3 100644 --- a/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml +++ b/src/WinGetUtilInterop.UnitTests/TestCollateral/V1_9ManifestMerged.yaml @@ -250,4 +250,4 @@ Installers: ProductCode: '{Bar}' MSStoreProductIdentifier: fakeIdentifier ManifestType: merged -ManifestVersion: 1.7.0 +ManifestVersion: 1.9.0 From a97593f631d562c4ea7b7be26e46c1bd73bf6f16 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Fri, 14 Feb 2025 19:56:18 -0800 Subject: [PATCH 2/9] applicability for choosing default install version --- .../CatalogPackage.cpp | 54 ++++++++++++++++--- .../PackageManager.cpp | 3 +- .../PackageManager.idl | 6 ++- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.Management.Deployment/CatalogPackage.cpp b/src/Microsoft.Management.Deployment/CatalogPackage.cpp index 756d6fbd60..87da09d908 100644 --- a/src/Microsoft.Management.Deployment/CatalogPackage.cpp +++ b/src/Microsoft.Management.Deployment/CatalogPackage.cpp @@ -10,6 +10,8 @@ #include "PackageVersionId.h" #include "PackageInstallerInstalledStatus.h" #include "CheckInstalledStatusResult.h" +#include +#include #include #include #include @@ -72,20 +74,58 @@ namespace winrt::Microsoft::Management::Deployment::implementation { using namespace AppInstaller::Pinning; + auto availableVersions = AppInstaller::Repository::GetAvailableVersionsForInstalledVersion(m_package); + auto installedVersion = AppInstaller::Repository::GetInstalledVersion(m_package); + PinningData pinningData{ PinningData::Disposition::ReadOnly }; - auto evaluator = pinningData.CreatePinStateEvaluator(PinBehavior::ConsiderPins, GetInstalledVersion(m_package)); + auto evaluator = pinningData.CreatePinStateEvaluator(PinBehavior::ConsiderPins, installedVersion); + + AppInstaller::CLI::Execution::COMContext context; + AppInstaller::Repository::IPackageVersion::Metadata installationMetadata = + installedVersion ? installedVersion->GetMetadata() : AppInstaller::Repository::IPackageVersion::Metadata{}; + AppInstaller::CLI::Workflow::ManifestComparator manifestComparator{ context, installationMetadata }; - std::shared_ptr<::AppInstaller::Repository::IPackageVersion> latestVersion = - evaluator.GetLatestAvailableVersionForPins(::AppInstaller::Repository::GetAvailableVersionsForInstalledVersion(m_package)); - if (latestVersion) + std::shared_ptr latestApplicableVersion; + auto availableVersionKeys = availableVersions->GetVersionKeys(); + for (const auto& availableVersionKey : availableVersionKeys) { - m_updateAvailable = evaluator.IsUpdate(latestVersion); + auto availableVersion = availableVersions->GetVersion(availableVersionKey); + + if (installedVersion && !evaluator.IsUpdate(availableVersion)) + { + // Version too low or different channel for upgrade + continue; + } + + if (evaluator.EvaluatePinType(availableVersion) != AppInstaller::Pinning::PinType::Unknown) + { + // Pinned + continue; + } + + auto manifestComparatorResult = manifestComparator.GetPreferredInstaller(availableVersion->GetManifest()); + if (!manifestComparatorResult.installer.has_value()) + { + // No applicable installer + continue; + } + latestApplicableVersion = availableVersion; + if (installedVersion) + { + m_updateAvailable = true; + } + + break; + } + + if (latestApplicableVersion) + { // DefaultInstallVersion hasn't been created yet, create and populate it. - // DefaultInstallVersion is the LatestAvailableVersion of the internal package object. + // DefaultInstallVersion is the latest applicable version of the internal package object. auto latestVersionImpl = winrt::make_self>(); - latestVersionImpl->Initialize(std::move(latestVersion)); + latestVersionImpl->Initialize(std::move(latestApplicableVersion)); m_defaultInstallVersion = *latestVersionImpl; } }); diff --git a/src/Microsoft.Management.Deployment/PackageManager.cpp b/src/Microsoft.Management.Deployment/PackageManager.cpp index 99ccf48829..f710b647ba 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment/PackageManager.cpp @@ -480,7 +480,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation } // If the specified version wasn't found then return a failure. This is unusual, since all packages that came from a non-local catalog have a default version, // and the versionId is strongly typed and comes from the CatalogPackage.GetAvailableVersions. - THROW_HR_IF(APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND, !packageVersionInfo); + // If version is not specified, DefaultInstallVersion may be empty due to applicability check. + THROW_HR_IF(versionId ? APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND : APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER, !packageVersionInfo); return packageVersionInfo; } diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index 29f2e9166a..dd113cc031 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -1030,8 +1030,10 @@ namespace Microsoft.Management.Deployment { InstallOptions(); - /// Optionally specifies the version from the package to install. If unspecified the version matching - /// CatalogPackage.GetLatestVersion() is used. + /// Optionally specifies the version from the package to install. If unspecified, the CatalogPackage.DefaultInstallVersion + /// version is used. DefaultInstallVersion is the latest applicable version of the package. DefaultInstallVersion may be + /// empty if there's no applicable version. In that case, install attempts without setting this PackageVersionId + /// will return No Applicable Installer error code. PackageVersionId PackageVersionId; /// Specifies alternate location to install package (if supported). From 9cc68a1efeec9938cd72bd5e5fe8abd1b5cdc1ef Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:33:13 -0800 Subject: [PATCH 3/9] IsUpdateAvailable test --- .../Interop/UpgradeInterop.cs | 68 ++++++++++++++++++- .../TestUpgradeAvailableApi.1.0.0.0.yaml | 20 ++++++ .../TestUpgradeAvailableApi.2.0.0.0.yaml | 20 ++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.1.0.0.0.yaml create mode 100644 src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.2.0.0.0.yaml diff --git a/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs b/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs index 9497a1000d..753a514284 100644 --- a/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs +++ b/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -8,7 +8,8 @@ namespace AppInstallerCLIE2ETests.Interop { using System; using System.Collections.Generic; - using System.IO; + using System.IO; + using System.Linq; using System.Threading.Tasks; using AppInstallerCLIE2ETests.Helpers; using Microsoft.Management.Deployment; @@ -230,6 +231,69 @@ public async Task UpgradePortableUninstallPrevious() searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "3.0.0.0"); TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + /// + /// Tests IsUpdateAvailable. + /// + /// A representing the asynchronous unit test. + [Test] + public async Task TestIsUpdateAvailable_ApplicableTrue() + { + // Find and install the test package. Install the version 1.0.0.0. + var installDir = TestCommon.GetRandomTestDir(); + var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); + var installOptions = this.TestFactory.CreateInstallOptions(); + installOptions.PreferredInstallLocation = installDir; + installOptions.PackageVersionId = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); + var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); + Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); + + // Find package again, but this time it should detect the installed version. + searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); + + // The installed version is 1.0.0.0. + Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + + // IsUpdateAvailable is true. + Assert.True(searchResult.CatalogPackage.IsUpdateAvailable); + + // Uninstall to clean up. + var uninstallOptions = this.TestFactory.CreateUninstallOptions(); + var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions); + } + + /// + /// Tests applicability check is performed for IsUpdateAvailable api. + /// + /// A representing the asynchronous unit test. + [Test] + public async Task TestIsUpdateAvailable_ApplicableFalse() + { + // Find and install the test package. Install the version 1.0.0.0. + var installDir = TestCommon.GetRandomTestDir(); + var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); + var installOptions = this.TestFactory.CreateInstallOptions(); + installOptions.PreferredInstallLocation = installDir; + installOptions.PackageVersionId = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); + var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); + Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); + + // Find package again, but this time it should detect the installed version. + searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); + + // The installed version is 1.0.0.0. + Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + + // There is version 2.0.0.0 in the package available versions. + Assert.True(searchResult.CatalogPackage.AvailableVersions.Any(v => v.Version == "2.0.0.0")); + + // IsUpdateAvailable is false due to applicability check. Only arm64 in version 2.0.0.0. + Assert.False(searchResult.CatalogPackage.IsUpdateAvailable); + + // Uninstall to clean up. + var uninstallOptions = this.TestFactory.CreateUninstallOptions(); + var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions); } // Cannot use foreach or Linq for out-of-process IVector diff --git a/src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.1.0.0.0.yaml b/src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.1.0.0.0.yaml new file mode 100644 index 0000000000..881e4dab5e --- /dev/null +++ b/src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.1.0.0.0.yaml @@ -0,0 +1,20 @@ +Id: AppInstallerTest.TestUpgradeApplicability +Name: TestUpgradeApplicability +Version: 1.0.0.0 +Publisher: AppInstallerTest +License: Test +Installers: + - Arch: x86 + Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe + Sha256: + InstallerType: exe + ProductCode: '{bfb0f666-99d5-433d-8a2e-32f31d4f8e48}' + Switches: + Custom: '/ProductID {bfb0f666-99d5-433d-8a2e-32f31d4f8e48} /DisplayName TestUpgradeApplicability' + SilentWithProgress: /exeswp + Silent: /exesilent + Interactive: /exeinteractive + Language: /exeenus + Log: /LogFile + InstallLocation: /InstallDir +ManifestVersion: 0.1.0 diff --git a/src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.2.0.0.0.yaml b/src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.2.0.0.0.yaml new file mode 100644 index 0000000000..0a58e3ae1e --- /dev/null +++ b/src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.2.0.0.0.yaml @@ -0,0 +1,20 @@ +Id: AppInstallerTest.TestUpgradeApplicability +Name: TestUpgradeApplicability +Version: 2.0.0.0 +Publisher: AppInstallerTest +License: Test +Installers: + - Arch: arm64 + Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe + Sha256: + InstallerType: exe + ProductCode: '{bfb0f666-99d5-433d-8a2e-32f31d4f8e48}' + Switches: + Custom: '/ProductID {bfb0f666-99d5-433d-8a2e-32f31d4f8e48} /DisplayName TestUpgradeApplicability' + SilentWithProgress: /exeswp + Silent: /exesilent + Interactive: /exeinteractive + Language: /exeenus + Log: /LogFile + InstallLocation: /InstallDir +ManifestVersion: 0.1.0 From f51a29744507025b5b87e97190b87cd6735bfb62 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Wed, 19 Feb 2025 15:07:10 -0800 Subject: [PATCH 4/9] rest multi version tests --- .../RestInterface_1_0.cpp | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/AppInstallerCLITests/RestInterface_1_0.cpp b/src/AppInstallerCLITests/RestInterface_1_0.cpp index b8c834180e..9c060e1c54 100644 --- a/src/AppInstallerCLITests/RestInterface_1_0.cpp +++ b/src/AppInstallerCLITests/RestInterface_1_0.cpp @@ -53,6 +53,54 @@ namespace })delimiter"); } + utility::string_t GetManifestsResponse_MultipleVersions() + { + return _XPLATSTR( + R"delimiter({ + "Data": { + "PackageIdentifier": "Foo.Bar", + "Versions": [ + { + "PackageVersion": "5.0.0", + "DefaultLocale": { + "PackageLocale": "en-us", + "Publisher": "Foo", + "PackageName": "Bar", + "License": "Foo bar license", + "ShortDescription": "Foo bar description" + }, + "Installers": [ + { + "Architecture": "x64", + "InstallerSha256": "011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6", + "InstallerType": "exe", + "InstallerUrl": "https://installer.example.com/foobar.exe" + } + ] + }, + { + "PackageVersion": "6.0.0", + "DefaultLocale": { + "PackageLocale": "en-us", + "Publisher": "Foo", + "PackageName": "Bar", + "License": "Foo bar license", + "ShortDescription": "Foo bar description" + }, + "Installers": [ + { + "Architecture": "x64", + "InstallerSha256": "011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6", + "InstallerType": "exe", + "InstallerUrl": "https://installer.example.com/foobar.exe" + } + ] + } + ] + } + })delimiter"); + } + struct GoodManifest_AllFields { utility::string_t GetSampleManifest_AllFields() @@ -440,6 +488,22 @@ TEST_CASE("Search_Optimized_ManifestResponse", "[RestSource][Interface_1_0]") REQUIRE(manifest.Installers[0].Url == "https://installer.example.com/foobar.exe"); } +TEST_CASE("Search_Optimized_ManifestResponse_MultipleVersions", "[RestSource][Interface_1_0]") +{ + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) }; + AppInstaller::Repository::SearchRequest request; + PackageMatchFilter filter{ PackageMatchField::Id, MatchType::Exact, "Foo.Bar" }; + request.Filters.emplace_back(std::move(filter)); + Interface v1{ TestRestUriString, std::move(helper) }; + Schema::IRestClient::SearchResult result = v1.Search(request); + REQUIRE(result.Matches.size() == 1); + REQUIRE(result.Matches[0].Versions.size() == 2); + REQUIRE(result.Matches[0].Versions[0].VersionAndChannel.GetVersion().ToString() == "5.0.0"); + REQUIRE(result.Matches[0].Versions[0].Manifest); + REQUIRE(result.Matches[0].Versions[1].VersionAndChannel.GetVersion().ToString() == "6.0.0"); + REQUIRE(result.Matches[0].Versions[1].Manifest); +} + TEST_CASE("Search_Optimized_NoResponse_NotFoundCode", "[RestSource][Interface_1_0]") { HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) }; @@ -481,6 +545,18 @@ TEST_CASE("GetManifests_GoodResponse_404AsEmpty", "[RestSource][Interface_1_0]") REQUIRE(manifests.size() == 0); } +TEST_CASE("GetManifests_GoodResponse_MultipleVersions", "[RestSource][Interface_1_0]") +{ + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) }; + Interface v1{ TestRestUriString, std::move(helper) }; + + // GetManifests + std::vector manifests = v1.GetManifests("Foo.Bar"); + REQUIRE(manifests.size() == 2); + REQUIRE(manifests[0].Version == "5.0.0"); + REQUIRE(manifests[1].Version == "6.0.0"); +} + TEST_CASE("GetManifests_BadResponse_SuccessCode", "[RestSource][Interface_1_0]") { utility::string_t badManifest = _XPLATSTR( @@ -546,3 +622,24 @@ TEST_CASE("GetManifests_GoodResponse_UnknownInstaller", "[RestSource][Interface_ REQUIRE(manifest.Installers.at(0).BaseInstallerType == InstallerTypeEnum::Unknown); REQUIRE(manifest.Installers.at(0).ProductId.empty()); } + +TEST_CASE("GetManifestByVersion_GoodResponse_MultipleVersions_VersionFound", "[RestSource][Interface_1_0]") +{ + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) }; + Interface v1{ TestRestUriString, std::move(helper) }; + + // GetManifests + std::optional manifest = v1.GetManifestByVersion("Foo.Bar", "5.0.0", ""); + REQUIRE(manifest.has_value()); + REQUIRE(manifest->Version == "5.0.0"); +} + +TEST_CASE("GetManifestByVersion_GoodResponse_MultipleVersions_VersionNotFound", "[RestSource][Interface_1_0]") +{ + HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) }; + Interface v1{ TestRestUriString, std::move(helper) }; + + // GetManifests + std::optional manifest = v1.GetManifestByVersion("Foo.Bar", "7.0.0", ""); + REQUIRE_FALSE(manifest.has_value()); +} From 37e863312ac7fdfb0df7793060f61254a481e759 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Wed, 19 Feb 2025 21:01:26 -0800 Subject: [PATCH 5/9] fix tests? --- src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs | 6 ++---- .../Interop/UninstallInterop.cs | 7 +++++-- .../Interop/UpgradeInterop.cs | 8 +++++--- .../PackageManager.cpp | 13 ++++++++++++- .../PackageManager.idl | 6 ++---- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs b/src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs index 88fb61d5c0..dcc45a39e6 100644 --- a/src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs +++ b/src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs @@ -392,10 +392,8 @@ public static void VerifyPortablePackage( isAddedToPath = currentPathValue.Contains(portablePathValue); } - if (shouldExist) - { - RunAICLICommand("uninstall", $"--product-code {productCode} --force"); - } + // Always clean up as best effort. + RunAICLICommand("uninstall", $"--product-code {productCode} --force"); Assert.AreEqual(shouldExist, exeExists, $"Expected portable exe path: {exePath}"); Assert.AreEqual(shouldExist && !installDirectoryAddedToPath, symlinkExists, $"Expected portable symlink path: {symlinkPath}"); diff --git a/src/AppInstallerCLIE2ETests/Interop/UninstallInterop.cs b/src/AppInstallerCLIE2ETests/Interop/UninstallInterop.cs index a4f43adf54..d723416c7d 100644 --- a/src/AppInstallerCLIE2ETests/Interop/UninstallInterop.cs +++ b/src/AppInstallerCLIE2ETests/Interop/UninstallInterop.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -277,7 +277,10 @@ public async Task UninstallPortableModifiedSymlink() Assert.True(modifiedSymlinkInfo.Exists, "Modified symlink should still exist"); // Remove modified symlink as to not interfere with other tests - modifiedSymlinkInfo.Delete(); + modifiedSymlinkInfo.Delete(); + + // Uninstall again to clean up. + await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions()); } /// diff --git a/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs b/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs index 753a514284..43769af237 100644 --- a/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs +++ b/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs @@ -243,9 +243,10 @@ public async Task TestIsUpdateAvailable_ApplicableTrue() // Find and install the test package. Install the version 1.0.0.0. var installDir = TestCommon.GetRandomTestDir(); var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); + var installVersion = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); var installOptions = this.TestFactory.CreateInstallOptions(); installOptions.PreferredInstallLocation = installDir; - installOptions.PackageVersionId = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); + installOptions.PackageVersionId = installVersion; var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); @@ -272,10 +273,11 @@ public async Task TestIsUpdateAvailable_ApplicableFalse() { // Find and install the test package. Install the version 1.0.0.0. var installDir = TestCommon.GetRandomTestDir(); - var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); + var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); + var installVersion = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); var installOptions = this.TestFactory.CreateInstallOptions(); installOptions.PreferredInstallLocation = installDir; - installOptions.PackageVersionId = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); + installOptions.PackageVersionId = installVersion; var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); diff --git a/src/Microsoft.Management.Deployment/PackageManager.cpp b/src/Microsoft.Management.Deployment/PackageManager.cpp index f710b647ba..369ff79757 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment/PackageManager.cpp @@ -476,7 +476,18 @@ namespace winrt::Microsoft::Management::Deployment::implementation } else { - packageVersionInfo = package.DefaultInstallVersion(); + if constexpr (std::is_same_v) + { + packageVersionInfo = package.DefaultInstallVersion(); + } + else if constexpr (std::is_same_v) + { + // For download, applicability check is not needed. Just use latest. + if (package.AvailableVersions().Size() > 0) + { + packageVersionInfo = package.GetPackageVersionInfo(package.AvailableVersions().GetAt(0)); + } + } } // If the specified version wasn't found then return a failure. This is unusual, since all packages that came from a non-local catalog have a default version, // and the versionId is strongly typed and comes from the CatalogPackage.GetAvailableVersions. diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index dd113cc031..16576de5d9 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -1137,8 +1137,7 @@ namespace Microsoft.Management.Deployment { UninstallOptions(); - /// Optionally specifies the version from the package to uninstall. If unspecified the version matching - /// CatalogPackage.GetLatestVersion() is used. + /// This property is not currently used. The version of CatalogPackage.InstalledVersion is used for uninstall. PackageVersionId PackageVersionId; /// Silent, Interactive, or Default @@ -1234,8 +1233,7 @@ namespace Microsoft.Management.Deployment { RepairOptions(); - /// Optionally specifies the version from the package to repair. If unspecified the version matching - /// CatalogPackage.GetLatestVersion() is used. + /// This property is not currently used. The version of CatalogPackage.InstalledVersion is used for repair. PackageVersionId PackageVersionId; /// The package Repair scope. From 3c4306f6ff1757b9e3dd3855580631b7d7b4ddcf Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Thu, 20 Feb 2025 01:56:44 -0800 Subject: [PATCH 6/9] Fix tests --- .../Interop/UpgradeInterop.cs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs b/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs index 43769af237..51402f6817 100644 --- a/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs +++ b/src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs @@ -79,7 +79,7 @@ public async Task UpgradePortable() // Find package again, but this time it should detect the installed version searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion?.Version); // Configure upgrade options var upgradeOptions = this.TestFactory.CreateInstallOptions(); @@ -91,7 +91,7 @@ public async Task UpgradePortable() // Find package again, but this time it should detect the upgraded installed version searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "2.0.0.0"); + Assert.AreEqual("2.0.0.0", searchResult.CatalogPackage.InstalledVersion?.Version); TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); } @@ -138,7 +138,7 @@ public async Task UpgradePortableARPMismatch() // Find package again, it should have not been upgraded searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); } @@ -186,7 +186,7 @@ public async Task UpgradePortableForcedOverride() // Find package again, but this time it should detect the upgraded installed version searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "2.0.0.0"); + Assert.AreEqual("2.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); } @@ -217,7 +217,7 @@ public async Task UpgradePortableUninstallPrevious() // Find package again, but this time it should detect the installed version searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); // Configure upgrade options var upgradeOptions = this.TestFactory.CreateInstallOptions(); @@ -229,7 +229,7 @@ public async Task UpgradePortableUninstallPrevious() // Find package again, but this time it should detect the upgraded installed version searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId); - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "3.0.0.0"); + Assert.AreEqual("3.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); } @@ -243,10 +243,9 @@ public async Task TestIsUpdateAvailable_ApplicableTrue() // Find and install the test package. Install the version 1.0.0.0. var installDir = TestCommon.GetRandomTestDir(); var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); - var installVersion = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); var installOptions = this.TestFactory.CreateInstallOptions(); installOptions.PreferredInstallLocation = installDir; - installOptions.PackageVersionId = installVersion; + installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); @@ -254,7 +253,7 @@ public async Task TestIsUpdateAvailable_ApplicableTrue() searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestExeInstaller"); // The installed version is 1.0.0.0. - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); // IsUpdateAvailable is true. Assert.True(searchResult.CatalogPackage.IsUpdateAvailable); @@ -273,11 +272,10 @@ public async Task TestIsUpdateAvailable_ApplicableFalse() { // Find and install the test package. Install the version 1.0.0.0. var installDir = TestCommon.GetRandomTestDir(); - var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); - var installVersion = searchResult.CatalogPackage.AvailableVersions.Single(v => v.Version == "1.0.0.0"); + var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); var installOptions = this.TestFactory.CreateInstallOptions(); installOptions.PreferredInstallLocation = installDir; - installOptions.PackageVersionId = installVersion; + installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "1.0.0.0"); var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions); Assert.AreEqual(InstallResultStatus.Ok, installResult.Status); @@ -285,10 +283,10 @@ public async Task TestIsUpdateAvailable_ApplicableFalse() searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, "AppInstallerTest.TestUpgradeApplicability"); // The installed version is 1.0.0.0. - Assert.AreEqual(searchResult.CatalogPackage.InstalledVersion?.Version, "1.0.0.0"); + Assert.AreEqual("1.0.0.0", searchResult.CatalogPackage.InstalledVersion.Version); // There is version 2.0.0.0 in the package available versions. - Assert.True(searchResult.CatalogPackage.AvailableVersions.Any(v => v.Version == "2.0.0.0")); + Assert.NotNull(First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == "2.0.0.0")); // IsUpdateAvailable is false due to applicability check. Only arm64 in version 2.0.0.0. Assert.False(searchResult.CatalogPackage.IsUpdateAvailable); From 13a0c910272258f1a2980ee87540237ef7d8af07 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Thu, 20 Feb 2025 13:07:41 -0800 Subject: [PATCH 7/9] use before move --- src/AppInstallerCommonCore/Manifest/YamlParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AppInstallerCommonCore/Manifest/YamlParser.cpp b/src/AppInstallerCommonCore/Manifest/YamlParser.cpp index 86bbd23d84..7a6a416656 100644 --- a/src/AppInstallerCommonCore/Manifest/YamlParser.cpp +++ b/src/AppInstallerCommonCore/Manifest/YamlParser.cpp @@ -528,8 +528,8 @@ namespace AppInstaller::Manifest::YamlParser YamlManifestInfo manifestInfo; YAML::Document doc = YAML::LoadDocument(file.path()); - manifestInfo.Root = std::move(doc).GetRoot(); manifestInfo.DocumentSchemaHeader = doc.GetSchemaHeader(); + manifestInfo.Root = std::move(doc).GetRoot(); manifestInfo.FileName = file.path().filename().u8string(); docList.emplace_back(std::move(manifestInfo)); } @@ -538,8 +538,8 @@ namespace AppInstaller::Manifest::YamlParser { YamlManifestInfo manifestInfo; YAML::Document doc = YAML::LoadDocument(inputPath, manifestInfo.StreamSha256); - manifestInfo.Root = std::move(doc).GetRoot(); manifestInfo.DocumentSchemaHeader = doc.GetSchemaHeader(); + manifestInfo.Root = std::move(doc).GetRoot(); manifestInfo.FileName = inputPath.filename().u8string(); docList.emplace_back(std::move(manifestInfo)); } @@ -563,8 +563,8 @@ namespace AppInstaller::Manifest::YamlParser { YamlManifestInfo manifestInfo; YAML::Document doc = YAML::LoadDocument(input); - manifestInfo.Root = std::move(doc).GetRoot(); manifestInfo.DocumentSchemaHeader = doc.GetSchemaHeader(); + manifestInfo.Root = std::move(doc).GetRoot(); docList.emplace_back(std::move(manifestInfo)); } catch (const std::exception& e) From ae5a0b2fa2116469570548904669afefc2ef42f6 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:23:46 -0800 Subject: [PATCH 8/9] Fix pester tests --- .../PSObjects/PSUninstallResult.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs index e9119dbfcc..5d9fa60e31 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -57,7 +57,16 @@ public string Source { get { - return this.catalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name; + if (this.catalogPackage.DefaultInstallVersion != null) + { + return this.catalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name; + } + else if (this.catalogPackage.AvailableVersions.Count > 0) + { + return this.catalogPackage.GetPackageVersionInfo(this.catalogPackage.AvailableVersions[0]).PackageCatalog.Info.Name; + } + + return string.Empty; } } From df4a91acecdd6c6037a85100913d9b10f235db97 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Thu, 20 Feb 2025 17:58:41 -0800 Subject: [PATCH 9/9] Fix PS output class source name logic --- .../Extensions/CatalogPackageExtensions.cs | 22 ++++++++++++++++++- .../PSObjects/PSCatalogPackage.cs | 5 +++-- .../PSObjects/PSDownloadResult.cs | 7 +++--- .../PSObjects/PSFoundCatalogPackage.cs | 6 ++--- .../PSObjects/PSInstallResult.cs | 7 +++--- .../PSObjects/PSRepairResult.cs | 5 +++-- .../PSObjects/PSUninstallResult.cs | 14 +++--------- 7 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/Extensions/CatalogPackageExtensions.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/Extensions/CatalogPackageExtensions.cs index 19c5df2a88..987e23e4c6 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/Extensions/CatalogPackageExtensions.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/Extensions/CatalogPackageExtensions.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -36,5 +36,25 @@ public static string ToString( return $"{package.Name} [{package.Id}]"; } } + + /// + /// Gets the best effort source name of a that matches its Id. + /// This source name is used together with Id in operation output classes for display purposes. + /// + /// A instance. + /// The best effort source name of the package. + public static string? GetSourceName(this CatalogPackage package) + { + for (int i = 0; i < package.AvailableVersions.Count; ++i) + { + var versionInfo = package.GetPackageVersionInfo(package.AvailableVersions[i]); + if (versionInfo.Id == package.Id) + { + return versionInfo.PackageCatalog.Info.Name; + } + } + + return null; + } } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSCatalogPackage.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSCatalogPackage.cs index d35516d21e..cad651f27c 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSCatalogPackage.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSCatalogPackage.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -9,6 +9,7 @@ namespace Microsoft.WinGet.Client.Engine.PSObjects using System.Linq; using Microsoft.Management.Deployment; using Microsoft.WinGet.Client.Engine.Exceptions; + using Microsoft.WinGet.Client.Engine.Extensions; /// /// CatalogPackage wrapper object for displaying to PowerShell. @@ -64,7 +65,7 @@ public string? Source { get { - return this.CatalogPackageCOM.DefaultInstallVersion?.PackageCatalog.Info.Name; + return this.CatalogPackageCOM.GetSourceName(); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSDownloadResult.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSDownloadResult.cs index 7e72e87de0..1a1eb979ee 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSDownloadResult.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSDownloadResult.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -8,6 +8,7 @@ namespace Microsoft.WinGet.Client.Engine.PSObjects { using System; using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Engine.Extensions; /// /// PSDownloadResult. @@ -53,11 +54,11 @@ public string Name /// /// Gets the source name of the downloaded package. /// - public string Source + public string? Source { get { - return this.catalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name; + return this.catalogPackage.GetSourceName(); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSFoundCatalogPackage.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSFoundCatalogPackage.cs index 54ff304968..a01b9ce9d6 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSFoundCatalogPackage.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSFoundCatalogPackage.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -25,9 +25,9 @@ internal PSFoundCatalogPackage(CatalogPackage catalogPackage) /// /// Gets the default install version of the catalog package. /// - public string Version + public string? Version { - get { return this.CatalogPackageCOM.DefaultInstallVersion.Version; } + get { return this.CatalogPackageCOM.DefaultInstallVersion?.Version; } } } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSInstallResult.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSInstallResult.cs index 489bd65c4d..7f263753d9 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSInstallResult.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSInstallResult.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. Licensed under the MIT License. // @@ -8,6 +8,7 @@ namespace Microsoft.WinGet.Client.Engine.PSObjects { using System; using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Engine.Extensions; /// /// PSInstallResult. @@ -53,11 +54,11 @@ public string Name /// /// Gets the source name of the installed package. /// - public string Source + public string? Source { get { - return this.catalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name; + return this.catalogPackage.GetSourceName(); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSRepairResult.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSRepairResult.cs index 6a991016c0..f9fd7ff3d3 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSRepairResult.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSRepairResult.cs @@ -8,6 +8,7 @@ namespace Microsoft.WinGet.Client.Engine.PSObjects { using System; using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Engine.Extensions; /// /// PSRepairResult. @@ -53,11 +54,11 @@ public string Name /// /// Gets the source name of the repaired package. /// - public string Source + public string? Source { get { - return this.catalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name; + return this.catalogPackage.GetSourceName(); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs index 5d9fa60e31..adff194212 100644 --- a/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs +++ b/src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs @@ -8,6 +8,7 @@ namespace Microsoft.WinGet.Client.Engine.PSObjects { using System; using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Engine.Extensions; /// /// UninstallResult wrapper object for displaying to PowerShell. @@ -53,20 +54,11 @@ public string Name /// /// Gets the source name of the uninstalled package. /// - public string Source + public string? Source { get { - if (this.catalogPackage.DefaultInstallVersion != null) - { - return this.catalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name; - } - else if (this.catalogPackage.AvailableVersions.Count > 0) - { - return this.catalogPackage.GetPackageVersionInfo(this.catalogPackage.AvailableVersions[0]).PackageCatalog.Info.Name; - } - - return string.Empty; + return this.catalogPackage.GetSourceName(); } }