Skip to content

Commit

Permalink
resolve merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
ryfu-msft committed Oct 11, 2023
2 parents 792c465 + 3d60cec commit a8f0ced
Show file tree
Hide file tree
Showing 16 changed files with 248 additions and 684 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ deserializing
dest
devblogs
differentpath
DISMAPI
DIRECTONLY
distro
dll
Expand Down
10 changes: 5 additions & 5 deletions src/AppInstallerCLICore/Argument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace AppInstaller::CLI
case Execution::Args::Type::Command:
return { type, "command"_liv, "cmd"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };
case Execution::Args::Type::Source:
return { type, "source"_liv, 's', ArgTypeCategory::Source };
return { type, "source"_liv, 's', ArgTypeCategory::QuerySource };
case Execution::Args::Type::Count:
return { type, "count"_liv, 'n', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };
case Execution::Args::Type::Exact:
Expand Down Expand Up @@ -223,11 +223,11 @@ namespace AppInstaller::CLI
return { type, "force"_liv, ArgTypeCategory::CopyFlagToSubContext };

case Execution::Args::Type::DependencySource:
return { type, "dependency-source"_liv, ArgTypeCategory::Source };
return { type, "dependency-source"_liv, ArgTypeCategory::ExtendedSource };
case Execution::Args::Type::CustomHeader:
return { type, "header"_liv, ArgTypeCategory::Source };
return { type, "header"_liv, ArgTypeCategory::QuerySource };
case Execution::Args::Type::AcceptSourceAgreements:
return { type, "accept-source-agreements"_liv, ArgTypeCategory::Source };
return { type, "accept-source-agreements"_liv, ArgTypeCategory::ExtendedSource };

case Execution::Args::Type::ToolVersion:
return { type, "version"_liv, 'v' };
Expand Down Expand Up @@ -465,7 +465,7 @@ namespace AppInstaller::CLI

// If a manifest is specified, we cannot also have arguments for searching
if (WI_IsFlagSet(categories, ArgTypeCategory::Manifest) &&
WI_IsAnyFlagSet(categories, ArgTypeCategory::PackageQuery | ArgTypeCategory::Source))
WI_IsAnyFlagSet(categories, ArgTypeCategory::PackageQuery | ArgTypeCategory::QuerySource))
{
throw CommandException(Resource::String::BothManifestAndSearchQueryProvided);
}
Expand Down
10 changes: 7 additions & 3 deletions src/AppInstallerCLICore/Argument.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,19 @@ namespace AppInstaller::CLI
// Arguments for installer or uninstaller behavior, which do not work for multiple packages.
// E.g.: --override
SingleInstallerBehavior = 0x20,
// Arguments for selecting or interacting with the source.
// E.g.: --accept-source-agreements
Source = 0x40,
// Arguments for selecting or interacting with the source used for initial querying
// E.g.: --header
QuerySource = 0x40,
// Arguments that only make sense when talking about multiple packages
MultiplePackages = 0x80,
// Flag arguments that should be copied over when creating a sub-context
CopyFlagToSubContext = 0x100,
// Arguments with associated values that should be copied over when creating a sub-context
CopyValueToSubContext = 0x200,
// Arguments for selecting or interacting with dependencies or setting specific source behaviors
// E.g.: --dependency-source
// E.g.: --accept-source-agreements
ExtendedSource = 0x400,
};

DEFINE_ENUM_FLAG_OPERATORS(ArgTypeCategory);
Expand Down
3 changes: 2 additions & 1 deletion src/AppInstallerCLICore/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(DownloadDirectoryArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(Downloading);
WINGET_DEFINE_RESOURCE_STRINGID(EnableAdminSettingFailed);
WINGET_DEFINE_RESOURCE_STRINGID(EnableWindowsFeaturesSuccess);
WINGET_DEFINE_RESOURCE_STRINGID(EnablingWindowsFeature);
WINGET_DEFINE_RESOURCE_STRINGID(ErrorCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(ErrorCommandShortDescription);
Expand Down Expand Up @@ -228,7 +229,7 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(IncludeUnknownArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(IncludeUnknownInListArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(IncompatibleArgumentsProvided);
WINGET_DEFINE_RESOURCE_STRINGID(InstallationAbandoned);
WINGET_DEFINE_RESOURCE_STRINGID(InstallAbandoned);
WINGET_DEFINE_RESOURCE_STRINGID(InstallationDisclaimer1);
WINGET_DEFINE_RESOURCE_STRINGID(InstallationDisclaimer2);
WINGET_DEFINE_RESOURCE_STRINGID(InstallationDisclaimerMSStore);
Expand Down
132 changes: 72 additions & 60 deletions src/AppInstallerCLICore/Workflows/DependenciesFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
#include "ManifestComparator.h"
#include "InstallFlow.h"
#include "winget\DependenciesGraph.h"
#include "winget\WindowsFeature.h"
#include "DependencyNodeProcessor.h"
#include "ShellExecuteInstallerHandler.h"

using namespace AppInstaller::Repository;
using namespace AppInstaller::Manifest;
using namespace AppInstaller::WindowsFeature;

namespace AppInstaller::CLI::Workflow
{
Expand Down Expand Up @@ -136,82 +135,91 @@ namespace AppInstaller::CLI::Workflow

const auto& rootDependencies = context.Get<Execution::Data::Installer>()->Dependencies;

if (rootDependencies.Empty())
if (rootDependencies.Empty() || !rootDependencies.HasAnyOf(DependencyType::WindowsFeature))
{
return;
}

if (rootDependencies.HasAnyOf(DependencyType::WindowsFeature))
context << Workflow::EnsureRunningAsAdmin;

if (context.IsTerminated())
{
context << Workflow::EnsureRunningAsAdmin;
if (context.IsTerminated())
return;
}

bool isCancelled = false;
bool enableFeaturesFailed = false;
bool rebootRequired = false;
bool force = context.Args.Contains(Execution::Args::Type::Force);

rootDependencies.ApplyToType(DependencyType::WindowsFeature, [&context, &isCancelled, &enableFeaturesFailed, &force, &rebootRequired](Dependency dependency)
{
return;
}
if (enableFeaturesFailed && !force || isCancelled)
{
return;
}

HRESULT hr = S_OK;
std::shared_ptr<DismHelper> dismHelper = std::make_shared<DismHelper>();
auto featureName = dependency.Id();

bool force = context.Args.Contains(Execution::Args::Type::Force);
bool rebootRequired = false;
auto featureContextPtr = context.CreateSubContext();
Execution::Context& featureContext = *featureContextPtr;
auto previousThreadGlobals = featureContext.SetForCurrentThread();

rootDependencies.ApplyToType(DependencyType::WindowsFeature, [&context, &hr, &dismHelper, &force, &rebootRequired](Dependency dependency)
featureContext << Workflow::ShellExecuteEnableWindowsFeature(featureName);

if (featureContext.IsTerminated())
{
if (SUCCEEDED(hr) || force)
{
auto featureName = dependency.Id();
AICLI_LOG(Core, Verbose, << "Processing Windows Feature dependency [" << featureName << "]");
WindowsFeature::WindowsFeature windowsFeature = dismHelper->GetWindowsFeature(featureName);
isCancelled = true;
return;
}

if (windowsFeature.DoesExist())
{
if (!windowsFeature.IsEnabled())
{
Utility::LocIndString featureDisplayName = windowsFeature.GetDisplayName();
Utility::LocIndView locIndFeatureName{ featureName };

context.Reporter.Info() << Resource::String::EnablingWindowsFeature(featureDisplayName, locIndFeatureName) << std::endl;

AICLI_LOG(Core, Info, << "Enabling Windows Feature [" << featureName << "] returned with HRESULT: " << hr);
auto enableFeatureFunction = [&](IProgressCallback& progress)->HRESULT { return windowsFeature.Enable(progress); };
hr = context.Reporter.ExecuteWithProgress(enableFeatureFunction, true);

if (FAILED(hr))
{
AICLI_LOG(Core, Error, << "Failed to enable Windows Feature " << featureDisplayName << " [" << locIndFeatureName << "] with exit code: " << hr);
context.Reporter.Warn() << Resource::String::FailedToEnableWindowsFeature(featureDisplayName, locIndFeatureName) << std::endl
<< GetUserPresentableMessage(hr) << std::endl;
}

if (hr == ERROR_SUCCESS_REBOOT_REQUIRED || windowsFeature.GetRestartRequiredStatus() == DismRestartType::DismRestartRequired)
{
rebootRequired = true;
}
}
}
else
{
// Note: If a feature is not found, continue enabling the rest of the dependencies but block immediately after unless force arg is present.
AICLI_LOG(Core, Info, << "Windows Feature [" << featureName << "] does not exist");
hr = APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY;
context.Reporter.Warn() << Resource::String::WindowsFeatureNotFound(Utility::LocIndView{ featureName }) << std::endl;
}
}
});
Utility::LocIndView locIndFeatureName{ featureName };
DWORD result = featureContext.Get<Execution::Data::OperationReturnCode>();

if (FAILED(hr))
{
if (force)
if (result == ERROR_SUCCESS)
{
AICLI_LOG(Core, Info, << "Successfully enabled [" << featureName << "]");
}
else if (result == 0x800f080c) // DISMAPI_E_UNKNOWN_FEATURE
{
AICLI_LOG(Core, Warning, << "Windows Feature [" << featureName << "] does not exist");
enableFeaturesFailed = true;
featureContext.Reporter.Warn() << Resource::String::WindowsFeatureNotFound(locIndFeatureName) << std::endl;
}
else if (result == ERROR_SUCCESS_REBOOT_REQUIRED)
{
context.Reporter.Warn() << Resource::String::FailedToEnableWindowsFeatureOverridden << std::endl;
AICLI_LOG(Core, Info, << "Reboot required for [" << featureName << "]");
rebootRequired = true;
}
else
{
context.Reporter.Error() << Resource::String::FailedToEnableWindowsFeatureOverrideRequired << std::endl;
AICLI_TERMINATE_CONTEXT(hr);
AICLI_LOG(Core, Error, << "Failed to enable Windows Feature [" << featureName << "] with exit code: " << result);
enableFeaturesFailed = true;
featureContext.Reporter.Warn() << Resource::String::FailedToEnableWindowsFeature(locIndFeatureName, result) << std::endl;
}
});

if (isCancelled)
{
context.Reporter.Warn() << Resource::String::InstallAbandoned << std::endl;
AICLI_TERMINATE_CONTEXT(E_ABORT);
}

if (enableFeaturesFailed)
{
if (force)
{
context.Reporter.Warn() << Resource::String::FailedToEnableWindowsFeatureOverridden << std::endl;
}
else if (rebootRequired)
else
{
context.Reporter.Error() << Resource::String::FailedToEnableWindowsFeatureOverrideRequired << std::endl;
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES);
}
}
else
{
if (rebootRequired)
{
if (force)
{
Expand All @@ -223,6 +231,10 @@ namespace AppInstaller::CLI::Workflow
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_INSTALL);
}
}
else
{
context.Reporter.Info() << Resource::String::EnableWindowsFeaturesSuccess << std::endl;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLICore/Workflows/MsiInstallFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace AppInstaller::CLI::Workflow

if (!installResult)
{
context.Reporter.Warn() << Resource::String::InstallationAbandoned << std::endl;
context.Reporter.Warn() << Resource::String::InstallAbandoned << std::endl;
AICLI_TERMINATE_CONTEXT(E_ABORT);
}
else
Expand Down
Loading

0 comments on commit a8f0ced

Please sign in to comment.