winget-cli

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

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 }