Skip to content

Commit 4262a0f

Browse files
committed
make windows feature experimental (#3620)
1 parent f7c1a44 commit 4262a0f

File tree

10 files changed

+54
-0
lines changed

10 files changed

+54
-0
lines changed

doc/Settings.md

+11
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,15 @@ You can enable the feature as shown below.
272272
"experimentalFeatures": {
273273
"configuration": true
274274
},
275+
```
276+
277+
### windowsFeature
278+
279+
This feature enables the ability to enable Windows Feature dependencies during installation.
280+
You can enable the feature as shown below.
281+
282+
```json
283+
"experimentalFeatures": {
284+
"windowsFeature": true
285+
},
275286
```

schemas/JSON/settings/settings.schema.0.2.json

+5
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@
241241
"description": "Enable support for configuration",
242242
"type": "boolean",
243243
"default": false
244+
},
245+
"windowsFeature": {
246+
"description": "Enable support for enabling Windows Feature(s)",
247+
"type": "boolean",
248+
"default": false
244249
}
245250
}
246251
}

src/AppInstallerCLICore/Workflows/DependenciesFlow.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ namespace AppInstaller::CLI::Workflow
129129

130130
void EnableWindowsFeaturesDependencies(Execution::Context& context)
131131
{
132+
if (!Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::WindowsFeature))
133+
{
134+
return;
135+
}
136+
132137
const auto& rootDependencies = context.Get<Execution::Data::Installer>()->Dependencies;
133138

134139
if (rootDependencies.Empty())

src/AppInstallerCLIE2ETests/FeaturesCommand.cs

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public void EnableExperimentalFeatures()
5353
WinGetSettingsHelper.ConfigureFeature("experimentalArg", true);
5454
WinGetSettingsHelper.ConfigureFeature("experimentalCmd", true);
5555
WinGetSettingsHelper.ConfigureFeature("directMSI", true);
56+
WinGetSettingsHelper.ConfigureFeature("windowsFeature", true);
5657
var result = TestCommon.RunAICLICommand("features", string.Empty);
5758
Assert.True(result.StdOut.Contains("Enabled"));
5859
}

src/AppInstallerCLIE2ETests/InstallCommand.cs

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ namespace AppInstallerCLIE2ETests
1616
/// </summary>
1717
public class InstallCommand : BaseCommand
1818
{
19+
/// <summary>
20+
/// One time setup.
21+
/// </summary>
22+
[OneTimeSetUp]
23+
public void OneTimeSetup()
24+
{
25+
WinGetSettingsHelper.ConfigureFeature("windowsFeature", true);
26+
}
27+
1928
/// <summary>
2029
/// Set up.
2130
/// </summary>

src/AppInstallerCLITests/WindowsFeature.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ TEST_CASE("InstallFlow_WindowsFeatureDoesNotExist", "[windowsFeature]")
2424

2525
TestCommon::TempFile installResultPath("TestExeInstalled.txt");
2626

27+
TestCommon::TestUserSettings testSettings;
28+
testSettings.Set<Setting::EFWindowsFeature>(true);
29+
2730
std::ostringstream installOutput;
2831
TestContext context{ installOutput, std::cin };
2932
auto previousThreadGlobals = context.SetForCurrentThread();
@@ -57,6 +60,9 @@ TEST_CASE("InstallFlow_FailedToEnableWindowsFeature", "[windowsFeature]")
5760

5861
TestCommon::TempFile installResultPath("TestExeInstalled.txt");
5962

63+
TestCommon::TestUserSettings testSettings;
64+
testSettings.Set<Setting::EFWindowsFeature>(true);
65+
6066
std::ostringstream installOutput;
6167
TestContext context{ installOutput, std::cin };
6268
auto previousThreadGlobals = context.SetForCurrentThread();
@@ -92,6 +98,9 @@ TEST_CASE("InstallFlow_FailedToEnableWindowsFeature_Force", "[windowsFeature]")
9298

9399
TestCommon::TempFile installResultPath("TestExeInstalled.txt");
94100

101+
TestCommon::TestUserSettings testSettings;
102+
testSettings.Set<Setting::EFWindowsFeature>(true);
103+
95104
// Override with arbitrary DISM api error (DISMAPI_E_DISMAPI_NOT_INITIALIZED) and make windows feature discoverable.
96105
HRESULT dismErrorResult = 0xc0040001;
97106
LocIndString testFeatureDisplayName = LocIndString{ "Test Windows Feature"_liv };
@@ -139,6 +148,9 @@ TEST_CASE("InstallFlow_RebootRequired", "[windowsFeature]")
139148

140149
TestCommon::TempFile installResultPath("TestExeInstalled.txt");
141150

151+
TestCommon::TestUserSettings testSettings;
152+
testSettings.Set<Setting::EFWindowsFeature>(true);
153+
142154
// Override with reboot required HRESULT.
143155
auto mockDismHelperOverride = TestHook::MockDismHelper_Override();
144156
auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);
@@ -173,6 +185,9 @@ TEST_CASE("InstallFlow_RebootRequired_Force", "[windowsFeature]")
173185

174186
TestCommon::TempFile installResultPath("TestExeInstalled.txt");
175187

188+
TestCommon::TestUserSettings testSettings;
189+
testSettings.Set<Setting::EFWindowsFeature>(true);
190+
176191
// Override with reboot required HRESULT.
177192
auto mockDismHelperOverride = TestHook::MockDismHelper_Override();
178193
auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);

src/AppInstallerCommonCore/ExperimentalFeature.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ namespace AppInstaller::Settings
4040
return userSettings.Get<Setting::EFExperimentalArg>();
4141
case ExperimentalFeature::Feature::DirectMSI:
4242
return userSettings.Get<Setting::EFDirectMSI>();
43+
case ExperimentalFeature::Feature::WindowsFeature:
44+
return userSettings.Get<Setting::EFWindowsFeature>();
4345
default:
4446
THROW_HR(E_UNEXPECTED);
4547
}
@@ -69,6 +71,8 @@ namespace AppInstaller::Settings
6971
return ExperimentalFeature{ "Argument Sample", "experimentalArg", "https://aka.ms/winget-settings", Feature::ExperimentalArg };
7072
case Feature::DirectMSI:
7173
return ExperimentalFeature{ "Direct MSI Installation", "directMSI", "https://aka.ms/winget-settings", Feature::DirectMSI };
74+
case Feature::WindowsFeature:
75+
return ExperimentalFeature{ "Windows Feature Dependencies", "windowsFeature", "https://aka.ms/winget-settings", Feature::WindowsFeature };
7276
default:
7377
THROW_HR(E_UNEXPECTED);
7478
}

src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace AppInstaller::Settings
2323
None = 0x0,
2424
// Before making DirectMSI non-experimental, it should be part of manifest validation.
2525
DirectMSI = 0x1,
26+
WindowsFeature = 0x2,
2627
Max, // This MUST always be after all experimental features
2728

2829
// Features listed after Max will not be shown with the features command

src/AppInstallerCommonCore/Public/winget/UserSettings.h

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ namespace AppInstaller::Settings
7070
EFExperimentalCmd,
7171
EFExperimentalArg,
7272
EFDirectMSI,
73+
EFWindowsFeature,
7374
// Telemetry
7475
TelemetryDisable,
7576
// Install behavior
@@ -145,6 +146,7 @@ namespace AppInstaller::Settings
145146
SETTINGMAPPING_SPECIALIZATION(Setting::EFExperimentalCmd, bool, bool, false, ".experimentalFeatures.experimentalCmd"sv);
146147
SETTINGMAPPING_SPECIALIZATION(Setting::EFExperimentalArg, bool, bool, false, ".experimentalFeatures.experimentalArg"sv);
147148
SETTINGMAPPING_SPECIALIZATION(Setting::EFDirectMSI, bool, bool, false, ".experimentalFeatures.directMSI"sv);
149+
SETTINGMAPPING_SPECIALIZATION(Setting::EFWindowsFeature, bool, bool, false, ".experimentalFeatures.windowsFeature"sv);
148150
// Telemetry
149151
SETTINGMAPPING_SPECIALIZATION(Setting::TelemetryDisable, bool, bool, false, ".telemetry.disable"sv);
150152
// Install behavior

src/AppInstallerCommonCore/UserSettings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ namespace AppInstaller::Settings
259259
WINGET_VALIDATE_PASS_THROUGH(EFExperimentalCmd)
260260
WINGET_VALIDATE_PASS_THROUGH(EFExperimentalArg)
261261
WINGET_VALIDATE_PASS_THROUGH(EFDirectMSI)
262+
WINGET_VALIDATE_PASS_THROUGH(EFWindowsFeature)
262263
WINGET_VALIDATE_PASS_THROUGH(AnonymizePathForDisplay)
263264
WINGET_VALIDATE_PASS_THROUGH(TelemetryDisable)
264265
WINGET_VALIDATE_PASS_THROUGH(InteractivityDisable)

0 commit comments

Comments
 (0)