From 5948912cf8e552518784ea063dafbaa94cc8c977 Mon Sep 17 00:00:00 2001 From: Yao Sun Date: Fri, 14 Jan 2022 00:57:42 -0800 Subject: [PATCH 1/4] Com upgrade --- .../Commands/COMInstallCommand.cpp | 3 +- .../Workflows/DownloadFlow.cpp | 4 +- .../Workflows/DownloadFlow.h | 5 +- .../InstallOptions.cpp | 8 +++ .../PackageManager.cpp | 5 +- .../CatalogPackage.h | 2 +- .../Converters.cpp | 3 + .../InstallOptions.cpp | 8 +++ .../InstallOptions.h | 3 + .../PackageManager.cpp | 56 ++++++++++++++++++- .../PackageManager.h | 5 +- .../PackageManager.idl | 15 ++++- 12 files changed, 106 insertions(+), 11 deletions(-) diff --git a/src/AppInstallerCLICore/Commands/COMInstallCommand.cpp b/src/AppInstallerCLICore/Commands/COMInstallCommand.cpp index 2ebc86d3d4..57a4fc9bc4 100644 --- a/src/AppInstallerCLICore/Commands/COMInstallCommand.cpp +++ b/src/AppInstallerCLICore/Commands/COMInstallCommand.cpp @@ -27,8 +27,7 @@ namespace AppInstaller::CLI void COMInstallCommand::ExecuteInternal(Context& context) const { context << - Workflow::GetInstallerHash << - Workflow::VerifyInstallerHash << + Workflow::ReverifyInstallerHash << Workflow::InstallPackageInstaller; } } diff --git a/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp b/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp index 06fca0ad86..c158ed5673 100644 --- a/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp +++ b/src/AppInstallerCLICore/Workflows/DownloadFlow.cpp @@ -462,7 +462,7 @@ namespace AppInstaller::CLI::Workflow } } - void GetInstallerHash(Execution::Context& context) + void ReverifyInstallerHash(Execution::Context& context) { const auto& installer = context.Get().value(); @@ -490,6 +490,8 @@ namespace AppInstaller::CLI::Workflow AICLI_LOG(CLI, Error, << "Installer file not found."); AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); } + + context << VerifyInstallerHash; } void RenameDownloadedInstaller(Execution::Context& context) diff --git a/src/AppInstallerCLICore/Workflows/DownloadFlow.h b/src/AppInstallerCLICore/Workflows/DownloadFlow.h index 744de69467..7419ca4655 100644 --- a/src/AppInstallerCLICore/Workflows/DownloadFlow.h +++ b/src/AppInstallerCLICore/Workflows/DownloadFlow.h @@ -35,12 +35,11 @@ namespace AppInstaller::CLI::Workflow // Outputs: HashPair void GetMsixSignatureHash(Execution::Context& context); - // Gets the hash of the downloaded installer. - // Downloading already computes the hash, so this is only needed to re-verify the installer hash. + // Re-verify the installer hash. This is used in Com install commands where download and install are in separate phases. // Required Args: None // Inputs: InstallerPath, Installer // Outputs: HashPair - void GetInstallerHash(Execution::Context& context); + void ReverifyInstallerHash(Execution::Context& context); // Verifies that the downloaded installer hash matches the hash in the manifest. // Required Args: None diff --git a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp index e0d18b843c..ebef6fb126 100644 --- a/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp +++ b/src/Microsoft.Management.Deployment.Client/InstallOptions.cpp @@ -90,4 +90,12 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } + bool InstallOptions::AllowUpgradeToUnknownVersion() + { + throw hresult_not_implemented(); + } + void InstallOptions::AllowUpgradeToUnknownVersion(bool) + { + throw hresult_not_implemented(); + } } diff --git a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp index 84ab4553de..53a1a21ff0 100644 --- a/src/Microsoft.Management.Deployment.Client/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment.Client/PackageManager.cpp @@ -38,5 +38,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation { throw hresult_not_implemented(); } - + winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::UpgradePackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions) + { + throw hresult_not_implemented(); + } } diff --git a/src/Microsoft.Management.Deployment/CatalogPackage.h b/src/Microsoft.Management.Deployment/CatalogPackage.h index 7dc0f419ec..a245b58e84 100644 --- a/src/Microsoft.Management.Deployment/CatalogPackage.h +++ b/src/Microsoft.Management.Deployment/CatalogPackage.h @@ -22,7 +22,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion(); winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey); bool IsUpdateAvailable(); - + #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: ::AppInstaller::Repository::Source m_source; diff --git a/src/Microsoft.Management.Deployment/Converters.cpp b/src/Microsoft.Management.Deployment/Converters.cpp index 69f11a1683..d3f40ca1c6 100644 --- a/src/Microsoft.Management.Deployment/Converters.cpp +++ b/src/Microsoft.Management.Deployment/Converters.cpp @@ -198,6 +198,9 @@ namespace winrt::Microsoft::Management::Deployment::implementation case APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER: resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::NoApplicableInstallers; break; + case APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE: + resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::NoApplicableUpgrade; + break; case APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX: case APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED: case APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED: diff --git a/src/Microsoft.Management.Deployment/InstallOptions.cpp b/src/Microsoft.Management.Deployment/InstallOptions.cpp index 07814af6cc..b0599b318a 100644 --- a/src/Microsoft.Management.Deployment/InstallOptions.cpp +++ b/src/Microsoft.Management.Deployment/InstallOptions.cpp @@ -104,6 +104,14 @@ namespace winrt::Microsoft::Management::Deployment::implementation { return m_allowedArchitectures; } + bool InstallOptions::AllowUpgradeToUnknownVersion() + { + return m_allowUpgradeToUnknownVersion; + } + void InstallOptions::AllowUpgradeToUnknownVersion(bool value) + { + m_allowUpgradeToUnknownVersion = value; + } CoCreatableMicrosoftManagementDeploymentClass(InstallOptions); } diff --git a/src/Microsoft.Management.Deployment/InstallOptions.h b/src/Microsoft.Management.Deployment/InstallOptions.h index 6e29523907..e95fab3813 100644 --- a/src/Microsoft.Management.Deployment/InstallOptions.h +++ b/src/Microsoft.Management.Deployment/InstallOptions.h @@ -33,6 +33,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation hstring AdditionalPackageCatalogArguments(); void AdditionalPackageCatalogArguments(hstring const& value); winrt::Windows::Foundation::Collections::IVector AllowedArchitectures(); + bool AllowUpgradeToUnknownVersion(); + void AllowUpgradeToUnknownVersion(bool value); #if !defined(INCLUDE_ONLY_INTERFACE_METHODS) private: @@ -47,6 +49,7 @@ namespace winrt::Microsoft::Management::Deployment::implementation std::wstring m_additionalPackageCatalogArguments = L""; Windows::Foundation::Collections::IVector m_allowedArchitectures{ winrt::single_threaded_vector() }; + bool m_allowUpgradeToUnknownVersion = false; #endif }; } diff --git a/src/Microsoft.Management.Deployment/PackageManager.cpp b/src/Microsoft.Management.Deployment/PackageManager.cpp index 2dee2ca317..eca4c43369 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment/PackageManager.cpp @@ -341,6 +341,9 @@ namespace winrt::Microsoft::Management::Deployment::implementation Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo = GetPackageVersionInfo(package, options); AddPackageManifestToContext(packageVersionInfo, context.get()); + // If the installer has dependencies, DependencySource needs to be set. + context->Args.AddArg(Execution::Args::Type::DependencySource, ::AppInstaller::Utility::ConvertToUTF8(packageVersionInfo.PackageCatalog().Info().Name())); + // Note: AdditionalPackageCatalogArguments is not needed during install since the manifest is already known so no additional calls to the source are needed. The property is deprecated. return context; } @@ -402,7 +405,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation std::shared_ptr queueItemParam, winrt::Microsoft::Management::Deployment::CatalogPackage package = nullptr, winrt::Microsoft::Management::Deployment::InstallOptions options = nullptr, - std::wstring callerProcessInfoString = {}) + std::wstring callerProcessInfoString = {}, + bool isUpgrade = false) { winrt::hresult terminationHR = S_OK; hstring correlationData = (options) ? options.CorrelationData() : L""; @@ -422,6 +426,30 @@ namespace winrt::Microsoft::Management::Deployment::implementation { Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo = GetPackageVersionInfo(package, options); std::unique_ptr comContext = CreateContextFromInstallOptions(package, options, callerProcessInfoString); + + if (isUpgrade) + { + AppInstaller::Utility::VersionAndChannel installedVersion{ winrt::to_string(package.InstalledVersion().Version()), winrt::to_string(package.InstalledVersion().Channel()) }; + AppInstaller::Utility::VersionAndChannel upgradeVersion{ winrt::to_string(packageVersionInfo.Version()), winrt::to_string(packageVersionInfo.Channel()) }; + + if (installedVersion.IsUpdatedBy(upgradeVersion) || + (options.AllowUpgradeToUnknownVersion() && + AppInstaller::Utility::ICUCaseInsensitiveEquals(installedVersion.GetChannel().ToString(), upgradeVersion.GetChannel().ToString()) && + upgradeVersion.GetVersion().IsUnknown())) + { + // Set upgrade flag + comContext->SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerExecutionUseUpdate); + // Add installed version + winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo* installedVersionInfoImpl = get_self(package.InstalledVersion()); + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> internalInstalledVersion = installedVersionInfoImpl->GetRepositoryPackageVersion(); + comContext->Add(internalInstalledVersion); + } + else + { + co_return GetInstallResult(executionStage, APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE, correlationData, false); + } + } + queueItem = Execution::OrchestratorQueueItemFactory::CreateItemForInstall(std::wstring{ package.Id() }, std::wstring{ packageVersionInfo.PackageCatalog().Info().Id() }, std::move(comContext)); Execution::ContextOrchestrator::Instance().EnqueueAndRunItem(queueItem); @@ -552,6 +580,32 @@ namespace winrt::Microsoft::Management::Deployment::implementation return GetInstallOperation(true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString)); } + winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::UpgradePackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options) + { + hstring correlationData = (options) ? options.CorrelationData() : L""; + + // options and catalog can both be null, package must be set. + WINGET_RETURN_INSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package); + // the package should have an installed version to be upgraded. + WINGET_RETURN_INSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package.InstalledVersion()); + + HRESULT hr = S_OK; + std::wstring callerProcessInfoString; + try + { + // Check for permissions and get caller info for telemetry. + // This must be done before any co_awaits since it requires info from the rpc caller thread. + auto [hrGetCallerId, callerProcessId] = GetCallerProcessId(); + WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hrGetCallerId); + WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId)); + callerProcessInfoString = TryGetCallerProcessInfo(callerProcessId); + } + WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED); + WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hr); + + return GetInstallOperation(true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString), true /* isUpgrade */); + } + winrt::Windows::Foundation::IAsyncOperationWithProgress PackageManager::GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo) { hstring correlationData; diff --git a/src/Microsoft.Management.Deployment/PackageManager.h b/src/Microsoft.Management.Deployment/PackageManager.h index 23a28235c1..879fb0a7a5 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.h +++ b/src/Microsoft.Management.Deployment/PackageManager.h @@ -21,9 +21,12 @@ namespace winrt::Microsoft::Management::Deployment::implementation winrt::Microsoft::Management::Deployment::PackageCatalogReference CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options); winrt::Windows::Foundation::IAsyncOperationWithProgress InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options); - //Contract 2.0 + // Contract 2.0 winrt::Windows::Foundation::IAsyncOperationWithProgress GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo); + // Contract 4.0 + winrt::Windows::Foundation::IAsyncOperationWithProgress + UpgradePackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options); }; } diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index c20d1ca441..de1b313763 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -2,7 +2,7 @@ // Licensed under the MIT License. namespace Microsoft.Management.Deployment { - [contractversion(3)] + [contractversion(4)] apicontract WindowsPackageManagerContract{}; /// State of the install. @@ -59,6 +59,7 @@ namespace Microsoft.Management.Deployment InstallError, ManifestError, NoApplicableInstallers, + NoApplicableUpgrade, }; /// Result of the install @@ -525,6 +526,12 @@ namespace Microsoft.Management.Deployment // architecture after the first will simply be ignored. Windows.Foundation.Collections.IVector AllowedArchitectures { get; }; } + + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)] + { + /// Allow the upgrade to continue for upgrade packages with manifest versions Unknown. + Boolean AllowUpgradeToUnknownVersion; + } } [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)] @@ -554,6 +561,12 @@ namespace Microsoft.Management.Deployment /// Get install progress Windows.Foundation.IAsyncOperationWithProgress GetInstallProgress(CatalogPackage package, PackageCatalogInfo catalogInfo); } + + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)] + { + /// Upgrade the specified package + Windows.Foundation.IAsyncOperationWithProgress UpgradePackageAsync(CatalogPackage package, InstallOptions options); + } } /// Force midl3 to generate vector marshalling info. From 2b8a0fb5da4e4edbe5733ae0d9d6fa9ce69b3ab2 Mon Sep 17 00:00:00 2001 From: Yao Sun Date: Wed, 19 Jan 2022 20:23:04 -0800 Subject: [PATCH 2/4] pr comments, break down error codes --- src/AppInstallerCLIE2ETests/Constants.cs | 6 ++++ src/AppInstallerCommonCore/Errors.cpp | 16 ++++++++-- .../Public/AppInstallerErrors.h | 9 +++--- .../Converters.cpp | 2 ++ .../PackageManager.cpp | 31 ++++++++++--------- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/Constants.cs b/src/AppInstallerCLIE2ETests/Constants.cs index c2ee32a362..19ec2eddcc 100644 --- a/src/AppInstallerCLIE2ETests/Constants.cs +++ b/src/AppInstallerCLIE2ETests/Constants.cs @@ -142,6 +142,12 @@ public class ErrorCode public const int ERROR_MISSING_RESOURCE_FILE = unchecked((int)0x8A150048); public const int ERROR_MSI_INSTALL_FAILED = unchecked((int)0x8A150049); public const int ERROR_INVALID_MSIEXEC_ARGUMENT = unchecked((int)0x8A15004A); + public const int ERROR_FAILED_TO_OPEN_ALL_SOURCES = unchecked((int)0x8A15004B); + public const int ERROR_DEPENDENCIES_VALIDATION_FAILED = unchecked((int)0x8A15004C); + public const int ERROR_MISSING_PACKAGE = unchecked((int)0x8A15004D); + public const int ERROR_INVALID_TABLE_COLUMN = unchecked((int)0x8A15004E); + public const int ERROR_UPGRADE_VERSION_NOT_NEWER = unchecked((int)0x8A15004F); + public const int ERROR_UPGRADE_VERSION_UNKNOWN = unchecked((int)0x8A150050); public const int ERROR_INSTALL_PACKAGE_IN_USE = unchecked((int)0x8A150101); public const int ERROR_INSTALL_INSTALL_IN_PROGRESS = unchecked((int)0x8A150102); diff --git a/src/AppInstallerCommonCore/Errors.cpp b/src/AppInstallerCommonCore/Errors.cpp index 3c044113a2..c65027b980 100644 --- a/src/AppInstallerCommonCore/Errors.cpp +++ b/src/AppInstallerCommonCore/Errors.cpp @@ -146,8 +146,6 @@ namespace AppInstaller return "Package agreements were not agreed to"; case APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR: return "Error reading input in prompt"; - case APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT: - return "Arguments for msiexec are invalid"; case APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST: return "The search request is not supported by one or more sources"; case APPINSTALLER_CLI_ERROR_RESTSOURCE_ENDPOINT_NOT_FOUND: @@ -160,6 +158,20 @@ namespace AppInstaller return "Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again."; case APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED: return "Running MSI install failed"; + case APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT: + return "Arguments for msiexec are invalid"; + case APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES: + return "Failed to open one or more sources"; + case APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED: + return "Failed to validate dependencies"; + case APPINSTALLER_CLI_ERROR_MISSING_PACKAGE: + return "One or more package is missing"; + case APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN: + return "Invalid table column"; + case APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER: + return "The upgrade version is not newer than the installed version"; + case APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN: + return "Upgrade version is unknown and override is not specified"; case APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE: return "Application is currently running.Exit the application then try again."; case APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS: diff --git a/src/AppInstallerCommonCore/Public/AppInstallerErrors.h b/src/AppInstallerCommonCore/Public/AppInstallerErrors.h index 85b449bdb6..a87207f743 100644 --- a/src/AppInstallerCommonCore/Public/AppInstallerErrors.h +++ b/src/AppInstallerCommonCore/Public/AppInstallerErrors.h @@ -88,12 +88,13 @@ #define APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED ((HRESULT)0x8A150049) #define APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT ((HRESULT)0x8A15004A) #define APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES ((HRESULT)0x8A15004B) - -// Error associated with dependencies operations. -#define APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED ((HRESULT)0x8A15004C) +#define APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED ((HRESULT)0x8A15004C) #define APPINSTALLER_CLI_ERROR_MISSING_PACKAGE ((HRESULT)0x8A15004D) -#define APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN ((HRESULT)0x8A15004E) +#define APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN ((HRESULT)0x8A15004E) +#define APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER ((HRESULT)0x8A15004F) +#define APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN ((HRESULT)0x8A150050) +// Install errors. #define APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE ((HRESULT)0x8A150101) #define APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS ((HRESULT)0x8A150102) #define APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE ((HRESULT)0x8A150103) diff --git a/src/Microsoft.Management.Deployment/Converters.cpp b/src/Microsoft.Management.Deployment/Converters.cpp index d3f40ca1c6..29478b22f8 100644 --- a/src/Microsoft.Management.Deployment/Converters.cpp +++ b/src/Microsoft.Management.Deployment/Converters.cpp @@ -199,6 +199,8 @@ namespace winrt::Microsoft::Management::Deployment::implementation resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::NoApplicableInstallers; break; case APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE: + case APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN: + case APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER: resultStatus = winrt::Microsoft::Management::Deployment::InstallResultStatus::NoApplicableUpgrade; break; case APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX: diff --git a/src/Microsoft.Management.Deployment/PackageManager.cpp b/src/Microsoft.Management.Deployment/PackageManager.cpp index eca4c43369..93a07702c0 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.cpp +++ b/src/Microsoft.Management.Deployment/PackageManager.cpp @@ -341,9 +341,6 @@ namespace winrt::Microsoft::Management::Deployment::implementation Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo = GetPackageVersionInfo(package, options); AddPackageManifestToContext(packageVersionInfo, context.get()); - // If the installer has dependencies, DependencySource needs to be set. - context->Args.AddArg(Execution::Args::Type::DependencySource, ::AppInstaller::Utility::ConvertToUTF8(packageVersionInfo.PackageCatalog().Info().Name())); - // Note: AdditionalPackageCatalogArguments is not needed during install since the manifest is already known so no additional calls to the source are needed. The property is deprecated. return context; } @@ -432,22 +429,26 @@ namespace winrt::Microsoft::Management::Deployment::implementation AppInstaller::Utility::VersionAndChannel installedVersion{ winrt::to_string(package.InstalledVersion().Version()), winrt::to_string(package.InstalledVersion().Channel()) }; AppInstaller::Utility::VersionAndChannel upgradeVersion{ winrt::to_string(packageVersionInfo.Version()), winrt::to_string(packageVersionInfo.Channel()) }; - if (installedVersion.IsUpdatedBy(upgradeVersion) || - (options.AllowUpgradeToUnknownVersion() && - AppInstaller::Utility::ICUCaseInsensitiveEquals(installedVersion.GetChannel().ToString(), upgradeVersion.GetChannel().ToString()) && - upgradeVersion.GetVersion().IsUnknown())) + // Perform upgrade version check + if (upgradeVersion.GetVersion().IsUnknown()) { - // Set upgrade flag - comContext->SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerExecutionUseUpdate); - // Add installed version - winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo* installedVersionInfoImpl = get_self(package.InstalledVersion()); - std::shared_ptr<::AppInstaller::Repository::IPackageVersion> internalInstalledVersion = installedVersionInfoImpl->GetRepositoryPackageVersion(); - comContext->Add(internalInstalledVersion); + if (!(options.AllowUpgradeToUnknownVersion() && + AppInstaller::Utility::ICUCaseInsensitiveEquals(installedVersion.GetChannel().ToString(), upgradeVersion.GetChannel().ToString()))) + { + co_return GetInstallResult(executionStage, APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN, correlationData, false); + } } - else + else if (!installedVersion.IsUpdatedBy(upgradeVersion)) { - co_return GetInstallResult(executionStage, APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE, correlationData, false); + co_return GetInstallResult(executionStage, APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER, correlationData, false); } + + // Set upgrade flag + comContext->SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerExecutionUseUpdate); + // Add installed version + winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo* installedVersionInfoImpl = get_self(package.InstalledVersion()); + std::shared_ptr<::AppInstaller::Repository::IPackageVersion> internalInstalledVersion = installedVersionInfoImpl->GetRepositoryPackageVersion(); + comContext->Add(internalInstalledVersion); } queueItem = Execution::OrchestratorQueueItemFactory::CreateItemForInstall(std::wstring{ package.Id() }, std::wstring{ packageVersionInfo.PackageCatalog().Info().Id() }, std::move(comContext)); From 778413558c093466ec291ee9dfa1bd89753ceef6 Mon Sep 17 00:00:00 2001 From: Yao Sun Date: Thu, 20 Jan 2022 20:03:30 -0800 Subject: [PATCH 3/4] Add the contract version for new enum value --- src/Microsoft.Management.Deployment/PackageManager.idl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index de1b313763..cbbdc955a5 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -59,7 +59,11 @@ namespace Microsoft.Management.Deployment InstallError, ManifestError, NoApplicableInstallers, - NoApplicableUpgrade, + [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)] + { + NoApplicableUpgrade, + } + }; /// Result of the install From 41cbda0f9da3ed6c0a63f64c0c7dd05885f756c9 Mon Sep 17 00:00:00 2001 From: Yao Sun Date: Thu, 20 Jan 2022 20:07:37 -0800 Subject: [PATCH 4/4] remove extra line --- src/Microsoft.Management.Deployment/PackageManager.idl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.Management.Deployment/PackageManager.idl b/src/Microsoft.Management.Deployment/PackageManager.idl index cbbdc955a5..60f548f55c 100644 --- a/src/Microsoft.Management.Deployment/PackageManager.idl +++ b/src/Microsoft.Management.Deployment/PackageManager.idl @@ -63,7 +63,6 @@ namespace Microsoft.Management.Deployment { NoApplicableUpgrade, } - }; /// Result of the install