-
Notifications
You must be signed in to change notification settings - Fork 338
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Windows Customization: Add general system and virtualization feature …
…settings - Updates `ManagementInfrastructureHelper.cs` for enhanced Windows feature management, including a refactored method for checking feature availability with modifications to return more detailed feature information. - Introduced a `RestartHelper.cs` class with a method to restart the computer immediately, to avoid disruption I did not point existing callers from Environments to this method since they have additional telemetry for this space. I can file an issue to track consolidation here. - Updated `WindowsIdentityHelper.cs` with a new method to check for whether a user has the capability to acquire administrative privileges, not just whether the current process is running elevated. - Added `WindowsOptionalFeatures.cs` and `WindowsOptionalFeatureState.cs` to represent Windows optional features, including a new static class for feature names and descriptions and a class to represent the state of an optional feature, specifically for UI. - Introduced `ModifyLongPathsSetting.cs` and `ModifyWindowsOptionalFeatures.cs` for enabling/disabling Windows settings and optional features through PowerShell scripts which require elevation. This allows the full script content to be visible to the user when accepting or rejecting the UAC prompt providing extra transparency, this is done in the same way as environments feature management. There are limitations here in that if scripts are blocked on the machine we're unable to make this changes, but until we finish security review on the elevated server, this is the best we've got. - Expanded Windows Customization with new views and dialogs for managing general system settings and virtualization features, including `GeneralSystemView`, `ModifyFeaturesDialog`, and `VirtualizationFeatureManagementPage`, alongside updates to existing views to accommodate these new features.
- Loading branch information
Showing
28 changed files
with
1,540 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using CommunityToolkit.Mvvm.Input; | ||
|
||
namespace DevHome.Common.Helpers; | ||
|
||
public partial class RestartHelper | ||
{ | ||
[RelayCommand] | ||
public static void RestartComputer() | ||
{ | ||
var startInfo = new ProcessStartInfo | ||
{ | ||
WindowStyle = ProcessWindowStyle.Hidden, | ||
FileName = Environment.SystemDirectory + "\\shutdown.exe", | ||
Arguments = "-r -t 0", | ||
Verb = string.Empty, | ||
}; | ||
|
||
var process = new Process | ||
{ | ||
StartInfo = startInfo, | ||
}; | ||
process.Start(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System.Collections.Generic; | ||
using DevHome.Common.Environments.Helpers; | ||
|
||
namespace DevHome.Common.Helpers; | ||
|
||
public static class WindowsOptionalFeatures | ||
{ | ||
public const string Containers = "Containers"; | ||
public const string GuardedHost = "HostGuardian"; | ||
public const string HyperV = "Microsoft-Hyper-V-All"; | ||
public const string HyperVManagementTools = "Microsoft-Hyper-V-Tools-All"; | ||
public const string HyperVPlatform = "Microsoft-Hyper-V"; | ||
public const string VirtualMachinePlatform = "VirtualMachinePlatform"; | ||
public const string WindowsHypervisorPlatform = "HypervisorPlatform"; | ||
public const string WindowsSandbox = "Containers-DisposableClientVM"; | ||
public const string WindowsSubsystemForLinux = "Microsoft-Windows-Subsystem-Linux"; | ||
|
||
public static IEnumerable<string> VirtualMachineFeatures => new[] | ||
{ | ||
Containers, | ||
GuardedHost, | ||
HyperV, | ||
HyperVManagementTools, | ||
HyperVPlatform, | ||
VirtualMachinePlatform, | ||
WindowsHypervisorPlatform, | ||
WindowsSandbox, | ||
WindowsSubsystemForLinux, | ||
}; | ||
|
||
public static readonly Dictionary<string, string> FeatureDescriptions = new() | ||
{ | ||
{ Containers, GetFeatureDescription(nameof(Containers)) }, | ||
{ GuardedHost, GetFeatureDescription(nameof(GuardedHost)) }, | ||
{ HyperV, GetFeatureDescription(nameof(HyperV)) }, | ||
{ HyperVManagementTools, GetFeatureDescription(nameof(HyperVManagementTools)) }, | ||
{ HyperVPlatform, GetFeatureDescription(nameof(HyperVPlatform)) }, | ||
{ VirtualMachinePlatform, GetFeatureDescription(nameof(VirtualMachinePlatform)) }, | ||
{ WindowsHypervisorPlatform, GetFeatureDescription(nameof(WindowsHypervisorPlatform)) }, | ||
{ WindowsSandbox, GetFeatureDescription(nameof(WindowsSandbox)) }, | ||
{ WindowsSubsystemForLinux, GetFeatureDescription(nameof(WindowsSubsystemForLinux)) }, | ||
}; | ||
|
||
private static string GetFeatureDescription(string featureName) | ||
{ | ||
return StringResourceHelper.GetResource(featureName + "Description"); | ||
} | ||
|
||
public class FeatureInfo | ||
{ | ||
public string FeatureName { get; set; } | ||
|
||
public string DisplayName { get; set; } | ||
|
||
public string Description { get; set; } | ||
|
||
public bool IsEnabled { get; set; } | ||
|
||
public bool IsAvailable { get; set; } | ||
|
||
public FeatureAvailabilityKind AvailabilityKind { get; set; } | ||
|
||
public FeatureInfo(string featureName, string displayName, string description, FeatureAvailabilityKind availabilityKind) | ||
{ | ||
FeatureName = featureName; | ||
DisplayName = displayName; | ||
Description = description; | ||
AvailabilityKind = availabilityKind; | ||
IsEnabled = AvailabilityKind == FeatureAvailabilityKind.Enabled; | ||
IsAvailable = AvailabilityKind == FeatureAvailabilityKind.Enabled || AvailabilityKind == FeatureAvailabilityKind.Disabled; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using static DevHome.Common.Helpers.WindowsOptionalFeatures; | ||
|
||
namespace DevHome.Common.Models; | ||
|
||
public partial class WindowsOptionalFeatureState : ObservableObject | ||
{ | ||
public FeatureInfo Feature { get; } | ||
|
||
[ObservableProperty] | ||
private bool _isModifiable; | ||
|
||
private bool _isEnabled; | ||
|
||
public bool IsEnabled | ||
{ | ||
get => _isEnabled; | ||
set | ||
{ | ||
if (SetProperty(ref _isEnabled, value)) | ||
{ | ||
OnPropertyChanged(nameof(HasChanged)); | ||
} | ||
} | ||
} | ||
|
||
public bool HasChanged => IsEnabled != Feature.IsEnabled; | ||
|
||
public WindowsOptionalFeatureState(FeatureInfo feature, bool modifiable) | ||
{ | ||
Feature = feature; | ||
IsEnabled = feature.IsEnabled; | ||
IsModifiable = modifiable; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using Serilog; | ||
|
||
namespace DevHome.Common.Scripts; | ||
|
||
public static class ModifyLongPathsSetting | ||
{ | ||
public static ExitCode ModifyLongPaths(bool enabled, ILogger? log = null) | ||
{ | ||
var scriptString = enabled ? EnableScript : DisableScript; | ||
var process = new Process | ||
{ | ||
StartInfo = new ProcessStartInfo | ||
{ | ||
WindowStyle = ProcessWindowStyle.Hidden, | ||
FileName = "powershell.exe", | ||
Arguments = $"-ExecutionPolicy Bypass -Command {scriptString}", | ||
UseShellExecute = true, | ||
Verb = "runas", | ||
}, | ||
}; | ||
|
||
try | ||
{ | ||
process.Start(); | ||
process.WaitForExit(); | ||
|
||
return FromExitCode(process.ExitCode); | ||
} | ||
catch (Exception ex) | ||
{ | ||
log?.Error(ex, "Failed to modify Long Paths setting"); | ||
return ExitCode.Failure; | ||
} | ||
} | ||
|
||
public enum ExitCode | ||
{ | ||
Success = 0, | ||
Failure = 1, | ||
} | ||
|
||
private static ExitCode FromExitCode(int exitCode) | ||
{ | ||
return exitCode switch | ||
{ | ||
0 => ExitCode.Success, | ||
_ => ExitCode.Failure, | ||
}; | ||
} | ||
|
||
private const string EnableScript = | ||
@" | ||
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1 | ||
if ($?) { exit 0 } else { exit 1 } | ||
"; | ||
|
||
private const string DisableScript = | ||
@" | ||
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 0 | ||
if ($?) { exit 0 } else { exit 1 } | ||
"; | ||
} |
Oops, something went wrong.