InstallFlow.h (8666B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include "ExecutionContext.h" 5 #include <winget/Manifest.h> 6 7 namespace AppInstaller::CLI::Workflow 8 { 9 using namespace std::string_view_literals; 10 11 // Token specified in installer args will be replaced by proper value. 12 static constexpr std::string_view ARG_TOKEN_LOGPATH = "<LOGPATH>"sv; 13 static constexpr std::string_view ARG_TOKEN_INSTALLPATH = "<INSTALLPATH>"sv; 14 15 // Determines if an installer type is allowed to install/uninstall in parallel. 16 bool ExemptFromSingleInstallLocking(AppInstaller::Manifest::InstallerTypeEnum type); 17 18 namespace details 19 { 20 // These single type install flows should remain "internal" and only ExecuteInstallerForType should be used externally 21 // so that all installs can properly handle single install locking. 22 23 // Runs the installer via ShellExecute. 24 // Required Args: None 25 // Inputs: Installer, InstallerPath 26 // Outputs: None 27 void ShellExecuteInstall(Execution::Context& context); 28 29 // Runs an MSI installer directly via MSI APIs. 30 // Required Args: None 31 // Inputs: Installer, InstallerPath 32 // Outputs: None 33 void DirectMSIInstall(Execution::Context& context); 34 35 // Deploys the MSIX. 36 // Required Args: None 37 // Inputs: Manifest?, Installer || InstallerPath 38 // Outputs: None 39 void MsixInstall(Execution::Context& context); 40 41 // Runs the flow for installing a Portable package. 42 // Required Args: None 43 // Inputs: Installer, InstallerPath 44 // Outputs: None 45 void PortableInstall(Execution::Context& context); 46 47 // Runs the flow for installing a package from an archive. 48 // Required Args: None 49 // Inputs: Installer, InstallerPath, Manifest 50 // Outputs: None 51 void ArchiveInstall(Execution::Context& context); 52 } 53 54 // Ensures that there is an applicable installer. 55 // Required Args: None 56 // Inputs: Installer 57 // Outputs: None 58 void EnsureApplicableInstaller(Execution::Context& context); 59 60 // Shows the installation disclaimer. 61 // Required Args: None 62 // Inputs: None 63 // Outputs: None 64 void ShowInstallationDisclaimer(Execution::Context& context); 65 66 // Displays the installations notes after a successful install. 67 // Required Args: None 68 // Inputs: InstallationNotes 69 // Outputs: None 70 void DisplayInstallationNotes(Execution::Context& context); 71 72 // Checks if there are any included arguments that are not supported for the package. 73 // Required Args: None 74 // Inputs: Installer 75 // Outputs: None 76 void CheckForUnsupportedArgs(Execution::Context& context); 77 78 // Admin is required for machine scope install for installer types like portable, msix and msstore. 79 // Required Args: None 80 // Inputs: Installer 81 // Outputs: None 82 void EnsureRunningAsAdminForMachineScopeInstall(Execution::Context& context); 83 84 // Composite flow that chooses what to do based on the installer type. 85 // Required Args: None 86 // Inputs: Installer, InstallerPath 87 // Outputs: None 88 void ExecuteInstaller(Execution::Context& context); 89 90 // Composite flow that chooses what to do based on the installer type. 91 // Required Args: None 92 // Inputs: Installer, InstallerPath 93 // Outputs: None 94 struct ExecuteInstallerForType : public WorkflowTask 95 { 96 ExecuteInstallerForType(Manifest::InstallerTypeEnum installerType) : WorkflowTask("ExecuteInstallerForType"), m_installerType(installerType) {} 97 98 void operator()(Execution::Context& context) const override; 99 100 private: 101 Manifest::InstallerTypeEnum m_installerType; 102 }; 103 104 // Verifies parameters for install to ensure success. 105 // Required Args: None 106 // Inputs: 107 // Outputs: None 108 void EnsureSupportForInstall(Execution::Context& context); 109 110 // Reports the return code returned by the installer. 111 // Required Args: None 112 // Inputs: Manifest, Installer, InstallerResult 113 // Outputs: None 114 struct ReportInstallerResult : public WorkflowTask 115 { 116 ReportInstallerResult(std::string_view installerType, HRESULT hr, bool isHResult = false) : 117 WorkflowTask("ReportInstallerResult"), 118 m_installerType(installerType), 119 m_hr(hr), 120 m_isHResult(isHResult) {} 121 122 void operator()(Execution::Context& context) const override; 123 124 private: 125 // Installer type used when reporting failures. 126 std::string_view m_installerType; 127 // Result to return if the installer failed. 128 HRESULT m_hr; 129 // Whether the installer result is an HRESULT. This guides how we show it. 130 bool m_isHResult; 131 }; 132 133 // Reports manifest identity and shows installation disclaimer 134 // Required Args: None 135 // Inputs: Manifest 136 // Outputs: None 137 void ReportIdentityAndInstallationDisclaimer(Execution::Context& context); 138 139 // Installs a specific package installer. See also InstallSinglePackage & ProcessMultiplePackages 140 // Required Args: None 141 // Inputs: InstallerPath, Manifest, Installer, PackageVersion, InstalledPackageVersion? 142 // Outputs: None 143 void InstallPackageInstaller(Execution::Context& context); 144 145 // Installs the dependencies for a specific package. CreateDependencySubContexts should have been called before this task. 146 // Required Args: None 147 // Inputs: InstallerPath, Manifest, Installer, PackageVersion, InstalledPackageVersion? 148 // Outputs: None 149 void InstallDependencies(Execution::Context& context); 150 151 // Downloads all of the package dependencies of a specific package. Only used in the 'winget download' and COM download flows. 152 // Required Args: none 153 // Inputs: Manifest, Installer 154 // Outputs: None 155 void DownloadPackageDependencies(Execution::Context& context); 156 157 // Installs a single package. This also does the reporting, user interaction, and installer download 158 // for single-package installation. 159 // RequiredArgs: None 160 // Inputs: Manifest, Installer, PackageVersion, InstalledPackageVersion? 161 // Outputs: None 162 void InstallSinglePackage(Execution::Context& context); 163 164 // Processes multiple packages by handling download and/or install. This also does the reporting and user interaction needed. 165 // Required Args: None 166 // Inputs: PackageSubContexts 167 // Outputs: None 168 struct ProcessMultiplePackages : public WorkflowTask 169 { 170 // Flags to signal change from default behavior of the task. 171 enum class Flags : uint32_t 172 { 173 None = 0x00, 174 SkipPackageAgreements = 0x01, 175 IgnoreDependencies = 0x02, 176 StopOnFailure = 0x04, 177 RefreshPathVariable = 0x08, 178 DownloadOnly = 0x10, 179 }; 180 181 ProcessMultiplePackages( 182 StringResource::StringId dependenciesReportMessage, 183 HRESULT resultOnFailure, 184 Flags flags = Flags::None, 185 std::vector<HRESULT>&& ignorableInstallResults = {}); 186 187 void operator()(Execution::Context& context) const override; 188 189 private: 190 HRESULT m_resultOnFailure; 191 std::vector<HRESULT> m_ignorableInstallResults; 192 StringResource::StringId m_dependenciesReportMessage; 193 bool m_ignorePackageDependencies; 194 bool m_ensurePackageAgreements; 195 bool m_stopOnFailure; 196 bool m_refreshPathVariable; 197 bool m_downloadOnly; 198 }; 199 200 DEFINE_ENUM_FLAG_OPERATORS(ProcessMultiplePackages::Flags); 201 202 // Stores the existing set of packages in ARP. 203 // Required Args: None 204 // Inputs: Installer 205 // Outputs: ARPSnapshot 206 void SnapshotARPEntries(Execution::Context& context); 207 208 // Reports on the changes between the stored ARPSnapshot and the current values, 209 // and stores the product code of the ARP entry found for the package. 210 // Required Args: None 211 // Inputs: ARPSnapshot?, Manifest, PackageVersion 212 // Outputs: CorrelatedAppsAndFeaturesEntries? 213 void ReportARPChanges(Execution::Context& context); 214 215 // Records the installation to the tracking catalog. 216 // Required Args: None 217 // Inputs: PackageVersion?, Manifest, Installer, CorrelatedAppsAndFeaturesEntries? 218 // Outputs: None 219 void RecordInstall(Execution::Context& context); 220 }