mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-04-03 14:06:27 +00:00
Add option to revert previous changes to windows defaults
This commit is contained in:
@@ -251,9 +251,9 @@
|
|||||||
"Features": [
|
"Features": [
|
||||||
{
|
{
|
||||||
"FeatureId": "RemoveApps",
|
"FeatureId": "RemoveApps",
|
||||||
"Label": "Remove the apps specified in the 'Apps' parameter",
|
"Label": "apps",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Remove Apps",
|
"Action": "Remove",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -275,9 +275,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "RemoveAppsCustom",
|
"FeatureId": "RemoveAppsCustom",
|
||||||
"Label": "Remove custom selection of apps",
|
"Label": "custom selection of apps",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Remove Custom Apps",
|
"Action": "Remove",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -287,9 +287,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "RemoveCommApps",
|
"FeatureId": "RemoveCommApps",
|
||||||
"Label": "Remove the Mail, Calendar, and People apps",
|
"Label": "the Mail, Calendar, and People apps",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Remove Mail, Calendar & People",
|
"Action": "Remove",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -299,9 +299,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "RemoveW11Outlook",
|
"FeatureId": "RemoveW11Outlook",
|
||||||
"Label": "Remove the new Outlook for Windows app",
|
"Label": "the new Outlook for Windows app",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Remove Outlook for Windows",
|
"Action": "Remove",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -311,9 +311,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "RemoveGamingApps",
|
"FeatureId": "RemoveGamingApps",
|
||||||
"Label": "Remove the Xbox App and Xbox Gamebar",
|
"Label": "the Xbox App and Xbox Gamebar",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Remove Gaming Apps",
|
"Action": "Remove",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -323,9 +323,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "RemoveHPApps",
|
"FeatureId": "RemoveHPApps",
|
||||||
"Label": "Remove HP OEM applications",
|
"Label": "HP OEM applications",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Remove HP Apps",
|
"Action": "Remove",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -335,9 +335,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "CreateRestorePoint",
|
"FeatureId": "CreateRestorePoint",
|
||||||
"Label": "Create a system restore point",
|
"Label": "a system restore point",
|
||||||
"Category": null,
|
"Category": null,
|
||||||
"Action": "Create Restore Point",
|
"Action": "Create",
|
||||||
"RegistryKey": null,
|
"RegistryKey": null,
|
||||||
"ApplyText": null,
|
"ApplyText": null,
|
||||||
"UndoAction": null,
|
"UndoAction": null,
|
||||||
@@ -891,7 +891,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "HideSearchTb",
|
"FeatureId": "HideSearchTb",
|
||||||
"Label": "Hide search icon from the taskbar",
|
"Label": "on the taskbar",
|
||||||
"Category": "Taskbar",
|
"Category": "Taskbar",
|
||||||
"Action": "Hide Search",
|
"Action": "Hide Search",
|
||||||
"RegistryKey": "Hide_Search_Taskbar.reg",
|
"RegistryKey": "Hide_Search_Taskbar.reg",
|
||||||
@@ -903,7 +903,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "ShowSearchIconTb",
|
"FeatureId": "ShowSearchIconTb",
|
||||||
"Label": "Show search icon on the taskbar",
|
"Label": "on the taskbar",
|
||||||
"Category": "Taskbar",
|
"Category": "Taskbar",
|
||||||
"Action": "Show Search Icon",
|
"Action": "Show Search Icon",
|
||||||
"RegistryKey": "Show_Search_Icon.reg",
|
"RegistryKey": "Show_Search_Icon.reg",
|
||||||
@@ -915,7 +915,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "ShowSearchLabelTb",
|
"FeatureId": "ShowSearchLabelTb",
|
||||||
"Label": "Show search icon with label on the taskbar",
|
"Label": "on the taskbar",
|
||||||
"Category": "Taskbar",
|
"Category": "Taskbar",
|
||||||
"Action": "Show Search Label",
|
"Action": "Show Search Label",
|
||||||
"RegistryKey": "Show_Search_Icon_And_Label.reg",
|
"RegistryKey": "Show_Search_Icon_And_Label.reg",
|
||||||
@@ -927,7 +927,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FeatureId": "ShowSearchBoxTb",
|
"FeatureId": "ShowSearchBoxTb",
|
||||||
"Label": "Show search box on the taskbar",
|
"Label": "on the taskbar",
|
||||||
"Category": "Taskbar",
|
"Category": "Taskbar",
|
||||||
"Action": "Show Search Box",
|
"Action": "Show Search Box",
|
||||||
"RegistryKey": "Show_Search_Box.reg",
|
"RegistryKey": "Show_Search_Box.reg",
|
||||||
|
|||||||
Binary file not shown.
@@ -180,20 +180,20 @@
|
|||||||
<StackPanel x:Name="ButtonPanel"
|
<StackPanel x:Name="ButtonPanel"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
HorizontalAlignment="Center">
|
HorizontalAlignment="Center">
|
||||||
<Button x:Name="ApplyKofiBtn" Width="210" Height="32"
|
<Button x:Name="ApplyKofiBtn"
|
||||||
Style="{DynamicResource SecondaryButtonStyle}"
|
Width="200" Height="32" Margin="4,0"
|
||||||
Margin="0,0,12,0"
|
Style="{DynamicResource SecondaryButtonStyle}"
|
||||||
AutomationProperties.Name="Support the creator">
|
AutomationProperties.Name="Support the creator">
|
||||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||||
<TextBlock Text="" FontFamily="Segoe Fluent Icons" FontSize="14" VerticalAlignment="Center" Margin="0,0,8,-1"/>
|
<TextBlock Text="" FontFamily="Segoe Fluent Icons" FontSize="14" VerticalAlignment="Center" Margin="0,0,8,-1"/>
|
||||||
<TextBlock Text="Support the creator" VerticalAlignment="Center" FontSize="14" Margin="0,0,0,1"/>
|
<TextBlock Text="Support the creator" VerticalAlignment="Center" FontSize="14" Margin="0,0,0,1"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
<Button x:Name="ApplyCloseBtn" Width="100" Height="32"
|
<Button x:Name="ApplyCloseBtn"
|
||||||
|
Content="Close"
|
||||||
|
Width="200" Height="32" Margin="4,0"
|
||||||
Style="{DynamicResource PrimaryButtonStyle}"
|
Style="{DynamicResource PrimaryButtonStyle}"
|
||||||
AutomationProperties.Name="Close">
|
AutomationProperties.Name="Close"/>
|
||||||
<TextBlock Text="Close" VerticalAlignment="Center" FontSize="14" Margin="0,0,0,1"/>
|
|
||||||
</Button>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -352,8 +352,16 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Border x:Name="CheckBoxBorder" Grid.Column="0" Width="18" Height="18" Background="{DynamicResource CheckBoxBgColor}" BorderBrush="{DynamicResource CheckBoxBorderColor}" BorderThickness="1" CornerRadius="4" Margin="0,0,8,0">
|
<Border x:Name="CheckBoxBorder" Grid.Column="0" Width="18" Height="18" Background="{DynamicResource CheckBoxBgColor}" BorderBrush="{DynamicResource CheckBoxBorderColor}" BorderThickness="1" CornerRadius="4" Margin="0,0,8,0">
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBlock x:Name="CheckMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="12" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed"/>
|
<TextBlock x:Name="CheckMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="12" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0">
|
||||||
<TextBlock x:Name="IndeterminateMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="11" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed" Margin="1,1,0,0" />
|
<TextBlock.Clip>
|
||||||
|
<RectangleGeometry x:Name="CheckMarkClip" Rect="0,0,0,16"/>
|
||||||
|
</TextBlock.Clip>
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock x:Name="IndeterminateMark" Text="" FontFamily="Segoe Fluent Icons" FontSize="11" Foreground="{DynamicResource ButtonBg}" HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0" Margin="1,1,0,0">
|
||||||
|
<TextBlock.Clip>
|
||||||
|
<RectangleGeometry x:Name="IndeterminateMarkClip" Rect="0,0,0,16"/>
|
||||||
|
</TextBlock.Clip>
|
||||||
|
</TextBlock>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<ContentPresenter Grid.Column="1" VerticalAlignment="Center" Margin="0,0,0,2"/>
|
<ContentPresenter Grid.Column="1" VerticalAlignment="Center" Margin="0,0,0,2"/>
|
||||||
@@ -364,24 +372,60 @@
|
|||||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource CheckBoxHoverColor}"/>
|
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource CheckBoxHoverColor}"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsChecked" Value="True">
|
<Trigger Property="IsChecked" Value="True">
|
||||||
<Setter TargetName="CheckMark" Property="Visibility" Value="Visible"/>
|
|
||||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||||
<Setter TargetName="CheckMark" Property="Foreground" Value="White"/>
|
<Setter TargetName="CheckMark" Property="Foreground" Value="White"/>
|
||||||
|
<Setter TargetName="CheckMark" Property="Opacity" Value="1"/>
|
||||||
|
<Setter TargetName="IndeterminateMark" Property="Opacity" Value="0"/>
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||||
|
<RectAnimation Storyboard.TargetName="CheckMarkClip" Storyboard.TargetProperty="Rect" From="0,0,0,16" To="0,0,16,16" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<RectAnimation Storyboard.TargetName="CheckMarkClip" Storyboard.TargetProperty="Rect" From="0,0,16,16" To="16,0,0,16" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="CheckMark" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsChecked" Value="{x:Null}">
|
<Trigger Property="IsChecked" Value="{x:Null}">
|
||||||
<Setter TargetName="IndeterminateMark" Property="Visibility" Value="Visible"/>
|
|
||||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonBg}"/>
|
||||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource ButtonBg}"/>
|
||||||
<Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8"/>
|
<Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8"/>
|
||||||
<Setter TargetName="IndeterminateMark" Property="Foreground" Value="White"/>
|
<Setter TargetName="IndeterminateMark" Property="Foreground" Value="White"/>
|
||||||
|
<Setter TargetName="IndeterminateMark" Property="Opacity" Value="1"/>
|
||||||
|
<Setter TargetName="CheckMark" Property="Opacity" Value="0"/>
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||||
|
<RectAnimation Storyboard.TargetName="IndeterminateMarkClip" Storyboard.TargetProperty="Rect" From="0,0,0,16" To="0,0,16,16" Duration="0:0:0.25" FillBehavior="HoldEnd"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<RectAnimation Storyboard.TargetName="IndeterminateMarkClip" Storyboard.TargetProperty="Rect" From="0,0,16,16" To="16,0,0,16" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="IndeterminateMark" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.15" FillBehavior="HoldEnd"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsChecked" Value="False">
|
||||||
|
<Setter TargetName="CheckMark" Property="Opacity" Value="0"/>
|
||||||
|
<Setter TargetName="IndeterminateMark" Property="Opacity" Value="0"/>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="IsEnabled" Value="False">
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonDisabled}"/>
|
<Setter TargetName="CheckBoxBorder" Property="Background" Value="{DynamicResource ButtonDisabled}"/>
|
||||||
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource BorderColor}"/>
|
<Setter TargetName="CheckBoxBorder" Property="BorderBrush" Value="{DynamicResource BorderColor}"/>
|
||||||
<Setter Property="Foreground" Value="{DynamicResource ButtonTextDisabled}"/>
|
<Setter Property="Opacity" Value="0.4"/>
|
||||||
<Setter Property="Opacity" Value="0.6"/>
|
|
||||||
<Setter TargetName="CheckMark" Property="Foreground" Value="{DynamicResource ButtonTextDisabled}"/>
|
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<MultiTrigger>
|
<MultiTrigger>
|
||||||
<MultiTrigger.Conditions>
|
<MultiTrigger.Conditions>
|
||||||
@@ -753,6 +797,11 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Revert link -->
|
||||||
|
<Button x:Name="HomeRevertLinkBtn" HorizontalAlignment="Center" Margin="0,7,0,0" Style="{DynamicResource ActionLinkButtonStyle}" AutomationProperties.Name="Revert previous changes">
|
||||||
|
<TextBlock Text="Revert previous changes" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
|
||||||
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
@@ -1140,20 +1189,8 @@
|
|||||||
|
|
||||||
<!-- Review & Apply Section -->
|
<!-- Review & Apply Section -->
|
||||||
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" Background="{DynamicResource BgColor}">
|
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" Background="{DynamicResource BgColor}">
|
||||||
<Button x:Name="ReviewChangesBtn" Background="Transparent" BorderThickness="0" Cursor="Hand" HorizontalAlignment="Center" Margin="0,4,0,10" AutomationProperties.Name="Review selected changes">
|
<Button x:Name="ReviewChangesBtn" Style="{DynamicResource ActionLinkButtonStyle}" HorizontalAlignment="Center" Margin="0,4,0,10" AutomationProperties.Name="Review selected changes">
|
||||||
<Button.Template>
|
<TextBlock Text="Review selected changes" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
|
||||||
<ControlTemplate TargetType="Button">
|
|
||||||
<TextBlock x:Name="LinkText" Text="Review selected changes" FontSize="14" Foreground="{DynamicResource ButtonBg}" FontWeight="SemiBold" HorizontalAlignment="Center"/>
|
|
||||||
<ControlTemplate.Triggers>
|
|
||||||
<Trigger Property="IsMouseOver" Value="True">
|
|
||||||
<Setter TargetName="LinkText" Property="Foreground" Value="{DynamicResource ButtonHover}"/>
|
|
||||||
</Trigger>
|
|
||||||
<Trigger Property="IsPressed" Value="True">
|
|
||||||
<Setter TargetName="LinkText" Property="Foreground" Value="{DynamicResource ButtonPressed}"/>
|
|
||||||
</Trigger>
|
|
||||||
</ControlTemplate.Triggers>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Button.Template>
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button x:Name="DeploymentApplyBtn" Style="{DynamicResource PrimaryButtonStyle}" Width="190" Height="44" HorizontalAlignment="Center" AutomationProperties.Name="Apply Changes">
|
<Button x:Name="DeploymentApplyBtn" Style="{DynamicResource PrimaryButtonStyle}" Width="190" Height="44" HorizontalAlignment="Center" AutomationProperties.Name="Apply Changes">
|
||||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||||
|
|||||||
160
Schemas/RevertSettingsWindow.xaml
Normal file
160
Schemas/RevertSettingsWindow.xaml
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="Revert Changes"
|
||||||
|
Width="620"
|
||||||
|
Height="620"
|
||||||
|
MinWidth="560"
|
||||||
|
MinHeight="420"
|
||||||
|
ResizeMode="CanResize"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
WindowStyle="None"
|
||||||
|
AllowsTransparency="True"
|
||||||
|
Background="Transparent"
|
||||||
|
Topmost="True"
|
||||||
|
ShowInTaskbar="False">
|
||||||
|
|
||||||
|
<Window.Resources>
|
||||||
|
<Style x:Key="RevertItemBorderStyle" TargetType="Border">
|
||||||
|
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource BorderColor}"/>
|
||||||
|
<Setter Property="Padding" Value="4,6,4,6"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="RevertItemRowStyle" TargetType="StackPanel">
|
||||||
|
<Setter Property="Orientation" Value="Vertical"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="RevertItemUndoTextStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||||
|
<Setter Property="Opacity" Value="0.75"/>
|
||||||
|
<Setter Property="Margin" Value="30,-4,0,3"/>
|
||||||
|
<Setter Property="FontSize" Value="12"/>
|
||||||
|
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="RevertEmptyTextStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource FgColor}"/>
|
||||||
|
<Setter Property="Opacity" Value="0.85"/>
|
||||||
|
<Setter Property="Margin" Value="6,0,6,0"/>
|
||||||
|
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||||
|
</Style>
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<Border BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="8"
|
||||||
|
Background="{DynamicResource CardBgColor}"
|
||||||
|
Margin="25">
|
||||||
|
<Border.Effect>
|
||||||
|
<DropShadowEffect Color="Black"
|
||||||
|
Opacity="0.15"
|
||||||
|
BlurRadius="20"
|
||||||
|
ShadowDepth="0"
|
||||||
|
Direction="0"/>
|
||||||
|
</Border.Effect>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Row="0" x:Name="TitleBar" Height="40" Background="Transparent">
|
||||||
|
<TextBlock x:Name="TitleText"
|
||||||
|
Text="Revert Changes"
|
||||||
|
Foreground="{DynamicResource FgColor}"
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="16,0,0,0"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Margin="20,12,1,12">
|
||||||
|
<TextBlock x:Name="MessageText"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="Select which previously applied tweaks should be reverted to Windows defaults."
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
FontSize="14"
|
||||||
|
LineHeight="20"
|
||||||
|
Foreground="{DynamicResource FgColor}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Grid Grid.Row="2" Margin="20,0,20,10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<DockPanel Grid.Row="0" Margin="0,0,0,8">
|
||||||
|
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
|
||||||
|
<Button x:Name="RevertSelectAllBtn"
|
||||||
|
Content="Select All"
|
||||||
|
Height="30"
|
||||||
|
Padding="12,0"
|
||||||
|
Style="{DynamicResource SecondaryButtonStyle}"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
AutomationProperties.Name="Select All"/>
|
||||||
|
<Button x:Name="RevertClearBtn"
|
||||||
|
Content="Clear"
|
||||||
|
Height="30"
|
||||||
|
Padding="12,0"
|
||||||
|
Style="{DynamicResource SecondaryButtonStyle}"
|
||||||
|
AutomationProperties.Name="Clear"/>
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock x:Name="RevertSelectionCount"
|
||||||
|
Text="0 settings selected"
|
||||||
|
Foreground="{DynamicResource FgColor}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
DockPanel.Dock="Right"
|
||||||
|
Margin="0,0,6,0"/>
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
|
<Border Grid.Row="1"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
CornerRadius="6"
|
||||||
|
Background="{DynamicResource BgColor}">
|
||||||
|
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Padding="8" Margin="0,1,1,1">
|
||||||
|
<StackPanel x:Name="RevertItemsPanel"/>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<CheckBox x:Name="RevertRestartExplorerCheckBox"
|
||||||
|
Grid.Row="2"
|
||||||
|
Content="Restart the Windows Explorer process to apply all changes immediately"
|
||||||
|
IsChecked="False"
|
||||||
|
Margin="2,10,0,0"
|
||||||
|
AutomationProperties.Name="Restart the Windows Explorer process to apply all changes immediately"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Button Panel -->
|
||||||
|
<Border Grid.Row="3"
|
||||||
|
Background="{DynamicResource BgColor}"
|
||||||
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
BorderThickness="0,1,0,0"
|
||||||
|
Padding="16,12"
|
||||||
|
CornerRadius="0,0,8,8">
|
||||||
|
<StackPanel x:Name="ButtonPanel"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Right">
|
||||||
|
<Button x:Name="RevertApplyBtn"
|
||||||
|
Content="Revert Selected Settings"
|
||||||
|
Height="32" MinWidth="200" Margin="4,0"
|
||||||
|
Style="{DynamicResource PrimaryButtonStyle}"
|
||||||
|
IsEnabled="False"
|
||||||
|
AutomationProperties.Name="Revert Selected Settings"/>
|
||||||
|
<Button x:Name="RevertCancelBtn"
|
||||||
|
Content="Cancel"
|
||||||
|
Height="32" MinWidth="80" Margin="4,0"
|
||||||
|
Style="{DynamicResource SecondaryButtonStyle}"
|
||||||
|
AutomationProperties.Name="Cancel"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Window>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="4"
|
CornerRadius="4"
|
||||||
Padding="{TemplateBinding Padding}">
|
Padding="{TemplateBinding Padding}">
|
||||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,1"/>
|
||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@@ -90,6 +90,32 @@
|
|||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<!-- Shared link-style button used for text actions like review/revert links -->
|
||||||
|
<Style x:Key="ActionLinkButtonStyle" TargetType="Button">
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Cursor" Value="Hand"/>
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource ButtonBg}"/>
|
||||||
|
<Setter Property="FontSize" Value="14"/>
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||||
|
<Setter Property="Padding" Value="0"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource ButtonHover}"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource ButtonPressed}"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<!-- ProgressBar Style -->
|
<!-- ProgressBar Style -->
|
||||||
<Style x:Key="ApplyProgressBarStyle" TargetType="ProgressBar">
|
<Style x:Key="ApplyProgressBarStyle" TargetType="ProgressBar">
|
||||||
<Setter Property="Background" Value="{DynamicResource ButtonBorderColor}"/>
|
<Setter Property="Background" Value="{DynamicResource ButtonBorderColor}"/>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Prints all pending changes that will be made by the script
|
# Prints all pending changes that will be made by the script
|
||||||
function PrintPendingChanges {
|
function PrintPendingChanges {
|
||||||
|
$skippedParams = @()
|
||||||
|
$undoChanges = $script:Params.ContainsKey('Undo')
|
||||||
Write-Output "Win11Debloat will make the following changes:"
|
Write-Output "Win11Debloat will make the following changes:"
|
||||||
|
|
||||||
if ($script:Params['CreateRestorePoint']) {
|
if ($script:Params['CreateRestorePoint']) {
|
||||||
@@ -9,6 +11,17 @@ function PrintPendingChanges {
|
|||||||
if ($script:ControlParams -contains $parameterName) {
|
if ($script:ControlParams -contains $parameterName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if ($parameterName -eq 'Apps' -or $parameterName -eq 'CreateRestorePoint') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($undoChanges) {
|
||||||
|
$undoFeature = GetUndoFeatureForParam -paramKey $parameterName
|
||||||
|
if (-not $undoFeature) {
|
||||||
|
$skippedParams += $parameterName
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Print parameter description
|
# Print parameter description
|
||||||
switch ($parameterName) {
|
switch ($parameterName) {
|
||||||
@@ -46,9 +59,19 @@ function PrintPendingChanges {
|
|||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
if ($script:Features -and $script:Features.ContainsKey($parameterName)) {
|
if ($script:Features -and $script:Features.ContainsKey($parameterName)) {
|
||||||
$action = $script:Features[$parameterName].Action
|
$action = if ($undoChanges -and $script:Features[$parameterName].UndoAction) {
|
||||||
|
$script:Features[$parameterName].UndoAction
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$script:Features[$parameterName].Action
|
||||||
|
}
|
||||||
$message = $script:Features[$parameterName].Label
|
$message = $script:Features[$parameterName].Label
|
||||||
Write-Output "- $action $message"
|
if ($action) {
|
||||||
|
Write-Output "- $action $message"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Output "- $message"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Fallback: show the parameter name if no feature description is available
|
# Fallback: show the parameter name if no feature description is available
|
||||||
@@ -59,6 +82,18 @@ function PrintPendingChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($undoChanges -and $skippedParams.Count -gt 0) {
|
||||||
|
Write-Output ""
|
||||||
|
Write-Output "The following changes cannot be automatically undone and will be skipped:"
|
||||||
|
|
||||||
|
$uniqueSkipped = $skippedParams | Sort-Object -Unique
|
||||||
|
foreach ($skippedParam in $uniqueSkipped) {
|
||||||
|
$action = $script:Features[$skippedParam].Action
|
||||||
|
$message = $script:Features[$skippedParam].Label
|
||||||
|
Write-Output "- $action $message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Output ""
|
Write-Output ""
|
||||||
Write-Output ""
|
Write-Output ""
|
||||||
Write-Output "Press enter to execute the script or press CTRL+C to quit..."
|
Write-Output "Press enter to execute the script or press CTRL+C to quit..."
|
||||||
|
|||||||
@@ -11,6 +11,34 @@ function ExecuteParameter {
|
|||||||
if ($script:Features.ContainsKey($paramKey)) {
|
if ($script:Features.ContainsKey($paramKey)) {
|
||||||
$feature = $script:Features[$paramKey]
|
$feature = $script:Features[$paramKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$undoChanges = $script:Params.ContainsKey('Undo')
|
||||||
|
$undoFeature = if ($undoChanges) { GetUndoFeatureForParam -paramKey $paramKey } else { $null }
|
||||||
|
|
||||||
|
# In global undo mode, skip any parameter that does not define undo metadata.
|
||||||
|
if ($undoChanges -and -not $undoFeature) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# If this feature was requested in undo mode, use undo metadata from Features.json.
|
||||||
|
if ($undoChanges -and $undoFeature) {
|
||||||
|
$undoRegFile = $undoFeature.RegistryUndoKey
|
||||||
|
$usesOfflineHive = $script:Params.ContainsKey("Sysprep") -or $script:Params.ContainsKey("User")
|
||||||
|
$undoFolderPath = if ($usesOfflineHive) {
|
||||||
|
Join-Path $script:RegfilesPath (Join-Path 'Sysprep' (Join-Path 'Undo' $undoRegFile))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Join-Path $script:RegfilesPath (Join-Path 'Undo' $undoRegFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prefer dedicated Undo subfolder files when present, with fallback to legacy root location.
|
||||||
|
if (Test-Path $undoFolderPath) {
|
||||||
|
$undoRegFile = Join-Path 'Undo' $undoRegFile
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportRegistryFile "> $($undoFeature.UndoAction) $($undoFeature.Label)" $undoRegFile
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
# If feature has RegistryKey and ApplyText, use dynamic ImportRegistryFile
|
# If feature has RegistryKey and ApplyText, use dynamic ImportRegistryFile
|
||||||
if ($feature -and $feature.RegistryKey -and $feature.ApplyText) {
|
if ($feature -and $feature.RegistryKey -and $feature.ApplyText) {
|
||||||
@@ -139,13 +167,41 @@ function ExecuteParameter {
|
|||||||
# Executes all selected parameters/features
|
# Executes all selected parameters/features
|
||||||
function ExecuteAllChanges {
|
function ExecuteAllChanges {
|
||||||
# Build list of actionable parameters (skip control params and data-only params)
|
# Build list of actionable parameters (skip control params and data-only params)
|
||||||
|
$undoChanges = $script:Params.ContainsKey('Undo')
|
||||||
$actionableKeys = @()
|
$actionableKeys = @()
|
||||||
|
$paramsToRemove = @()
|
||||||
foreach ($paramKey in $script:Params.Keys) {
|
foreach ($paramKey in $script:Params.Keys) {
|
||||||
if ($script:ControlParams -contains $paramKey) { continue }
|
if ($script:ControlParams -contains $paramKey) { continue }
|
||||||
if ($paramKey -eq 'Apps') { continue }
|
if ($paramKey -eq 'Apps') { continue }
|
||||||
if ($paramKey -eq 'CreateRestorePoint') { continue }
|
if ($paramKey -eq 'CreateRestorePoint') { continue }
|
||||||
|
|
||||||
|
if ($undoChanges) {
|
||||||
|
$undoFeature = GetUndoFeatureForParam -paramKey $paramKey
|
||||||
|
if (-not $undoFeature) {
|
||||||
|
$paramsToRemove += $paramKey
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$actionableKeys += $paramKey
|
$actionableKeys += $paramKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($undoChanges -and $paramsToRemove.Count -gt 0) {
|
||||||
|
foreach ($paramKey in ($paramsToRemove | Sort-Object -Unique)) {
|
||||||
|
if ($script:Params.ContainsKey($paramKey)) {
|
||||||
|
$null = $script:Params.Remove($paramKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# If no undo-capable changes remain, disable explorer restart for this run.
|
||||||
|
if ($undoChanges -and $actionableKeys.Count -eq 0) {
|
||||||
|
if (-not $script:Params.ContainsKey('NoRestartExplorer')) {
|
||||||
|
$script:Params['NoRestartExplorer'] = $true
|
||||||
|
}
|
||||||
|
Write-Warning "None of the selected changes can be undone automatically."
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
$totalSteps = $actionableKeys.Count
|
$totalSteps = $actionableKeys.Count
|
||||||
if ($script:Params.ContainsKey("CreateRestorePoint")) { $totalSteps++ }
|
if ($script:Params.ContainsKey("CreateRestorePoint")) { $totalSteps++ }
|
||||||
@@ -174,7 +230,10 @@ function ExecuteAllChanges {
|
|||||||
$stepName = $paramKey
|
$stepName = $paramKey
|
||||||
if ($script:Features.ContainsKey($paramKey)) {
|
if ($script:Features.ContainsKey($paramKey)) {
|
||||||
$feature = $script:Features[$paramKey]
|
$feature = $script:Features[$paramKey]
|
||||||
if ($feature.ApplyText) {
|
if ($undoChanges -and $feature.UndoAction) {
|
||||||
|
$stepName = "$($feature.UndoAction) $($feature.Label)"
|
||||||
|
}
|
||||||
|
elseif ($feature.ApplyText) {
|
||||||
# Prefer explicit ApplyText when provided
|
# Prefer explicit ApplyText when provided
|
||||||
$stepName = $feature.ApplyText
|
$stepName = $feature.ApplyText
|
||||||
} elseif ($feature.Label) {
|
} elseif ($feature.Label) {
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ function Show-ApplyModal {
|
|||||||
$applyRebootPanel.Visibility = 'Visible'
|
$applyRebootPanel.Visibility = 'Visible'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$script:ApplyCompletionMessageEl.Text = "Your clean system is ready. Thanks for using Win11Debloat!"
|
$script:ApplyCompletionMessageEl.Text = "Your system is ready. Thanks for using Win11Debloat!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1484,6 +1484,57 @@ function Show-MainWindow {
|
|||||||
UpdateNavigationButtons
|
UpdateNavigationButtons
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Handle Home Revert link button
|
||||||
|
$homeRevertLinkBtn = $window.FindName('HomeRevertLinkBtn')
|
||||||
|
if ($homeRevertLinkBtn) {
|
||||||
|
if (-not (Test-Path $script:SavedSettingsFilePath)) {
|
||||||
|
$homeRevertLinkBtn.Visibility = 'Collapsed'
|
||||||
|
}
|
||||||
|
|
||||||
|
$homeRevertLinkBtn.Add_Click({
|
||||||
|
$savedSettings = LoadJsonFile -filePath $script:SavedSettingsFilePath -expectedVersion "1.0" -optionalFile
|
||||||
|
if (-not $savedSettings -or -not $savedSettings.Settings) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$revertSelection = Show-RevertSettingsModal -Owner $window -LastUsedSettings $savedSettings
|
||||||
|
$selectedFeatureIds = @($revertSelection.SelectedFeatureIds)
|
||||||
|
$shouldRestartExplorer = ($revertSelection.RestartExplorer -eq $true)
|
||||||
|
|
||||||
|
if (-not $selectedFeatureIds -or $selectedFeatureIds.Count -eq 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep runtime/control parameters and clear actionable selections before adding selected revert targets.
|
||||||
|
$actionableKeys = @()
|
||||||
|
foreach ($k in $script:Params.Keys) {
|
||||||
|
if ($script:ControlParams -notcontains $k) {
|
||||||
|
$actionableKeys += $k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($k in $actionableKeys) {
|
||||||
|
$script:Params.Remove($k)
|
||||||
|
}
|
||||||
|
|
||||||
|
AddParameter 'Undo'
|
||||||
|
|
||||||
|
foreach ($featureId in $selectedFeatureIds) {
|
||||||
|
if ($script:Features.ContainsKey($featureId)) {
|
||||||
|
$feature = $script:Features[$featureId]
|
||||||
|
if ($feature.RegistryUndoKey -and $feature.UndoAction) {
|
||||||
|
AddParameter $featureId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use the existing apply modal to execute and present progress/completion.
|
||||||
|
Show-ApplyModal -Owner $window -RestartExplorer $shouldRestartExplorer
|
||||||
|
|
||||||
|
# Close the main window after the apply dialog closes
|
||||||
|
$window.Close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
# Handle Home Default Mode button - apply defaults and navigate directly to overview
|
# Handle Home Default Mode button - apply defaults and navigate directly to overview
|
||||||
$homeDefaultModeBtn = $window.FindName('HomeDefaultModeBtn')
|
$homeDefaultModeBtn = $window.FindName('HomeDefaultModeBtn')
|
||||||
$homeDefaultModeBtn.Add_Click({
|
$homeDefaultModeBtn.Add_Click({
|
||||||
|
|||||||
225
Scripts/GUI/Show-RevertSettingsModal.ps1
Normal file
225
Scripts/GUI/Show-RevertSettingsModal.ps1
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
function Show-RevertSettingsModal {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[System.Windows.Window]$Owner = $null,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
$LastUsedSettings
|
||||||
|
)
|
||||||
|
|
||||||
|
Add-Type -AssemblyName PresentationFramework,PresentationCore,WindowsBase | Out-Null
|
||||||
|
|
||||||
|
$usesDarkMode = GetSystemUsesDarkMode
|
||||||
|
|
||||||
|
# Determine owner window
|
||||||
|
$ownerWindow = if ($Owner) { $Owner } else { $script:GuiWindow }
|
||||||
|
|
||||||
|
# Show overlay if owner window exists
|
||||||
|
$overlay = $null
|
||||||
|
$overlayWasAlreadyVisible = $false
|
||||||
|
if ($ownerWindow) {
|
||||||
|
try {
|
||||||
|
$overlay = $ownerWindow.FindName('ModalOverlay')
|
||||||
|
if ($overlay) {
|
||||||
|
$overlayWasAlreadyVisible = ($overlay.Visibility -eq 'Visible')
|
||||||
|
if (-not $overlayWasAlreadyVisible) {
|
||||||
|
$ownerWindow.Dispatcher.Invoke([action]{ $overlay.Visibility = 'Visible' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load XAML from file
|
||||||
|
$xaml = Get-Content -Path $script:RevertSettingsWindowSchema -Raw
|
||||||
|
$reader = [System.Xml.XmlReader]::Create([System.IO.StringReader]::new($xaml))
|
||||||
|
try {
|
||||||
|
$revertWindow = [System.Windows.Markup.XamlReader]::Load($reader)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$reader.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ownerWindow) {
|
||||||
|
try {
|
||||||
|
$revertWindow.Owner = $ownerWindow
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWindowThemeResources -window $revertWindow -usesDarkMode $usesDarkMode
|
||||||
|
|
||||||
|
$itemsPanel = $revertWindow.FindName('RevertItemsPanel')
|
||||||
|
$countText = $revertWindow.FindName('RevertSelectionCount')
|
||||||
|
$selectAllBtn = $revertWindow.FindName('RevertSelectAllBtn')
|
||||||
|
$clearBtn = $revertWindow.FindName('RevertClearBtn')
|
||||||
|
$applyBtn = $revertWindow.FindName('RevertApplyBtn')
|
||||||
|
$cancelBtn = $revertWindow.FindName('RevertCancelBtn')
|
||||||
|
$restartExplorerCheckbox = $revertWindow.FindName('RevertRestartExplorerCheckBox')
|
||||||
|
|
||||||
|
$entryCheckboxes = @()
|
||||||
|
$featureCheckboxStyle = $null
|
||||||
|
if ($ownerWindow) {
|
||||||
|
try {
|
||||||
|
$featureCheckboxStyle = $ownerWindow.FindResource('FeatureCheckboxStyle')
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($restartExplorerCheckbox -and $featureCheckboxStyle) {
|
||||||
|
$restartExplorerCheckbox.Style = $featureCheckboxStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($setting in $LastUsedSettings.Settings) {
|
||||||
|
if ($setting.Value -ne $true) { continue }
|
||||||
|
if ($setting.Name -eq 'Apps' -or $setting.Name -eq 'RemoveApps' -or $setting.Name -eq 'CreateRestorePoint') { continue }
|
||||||
|
|
||||||
|
$feature = $null
|
||||||
|
if ($script:Features.ContainsKey($setting.Name)) {
|
||||||
|
$feature = $script:Features[$setting.Name]
|
||||||
|
}
|
||||||
|
$undoFeature = GetUndoFeatureForParam -paramKey $setting.Name
|
||||||
|
|
||||||
|
$label = $setting.Name
|
||||||
|
if ($feature -and $feature.Label) {
|
||||||
|
if ($feature.Action) {
|
||||||
|
$label = "$($feature.Action) $($feature.Label)"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$label = $feature.Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$undoLabel = if ($undoFeature -and $undoFeature.Label) {
|
||||||
|
"$($undoFeature.UndoAction) $($undoFeature.Label)"
|
||||||
|
} else {
|
||||||
|
'No revert action available'
|
||||||
|
}
|
||||||
|
|
||||||
|
$canUndo = ($undoFeature -ne $null)
|
||||||
|
|
||||||
|
$itemBorder = New-Object System.Windows.Controls.Border
|
||||||
|
$itemBorder.Style = $revertWindow.FindResource('RevertItemBorderStyle')
|
||||||
|
|
||||||
|
$row = New-Object System.Windows.Controls.StackPanel
|
||||||
|
$row.Style = $revertWindow.FindResource('RevertItemRowStyle')
|
||||||
|
|
||||||
|
$checkbox = New-Object System.Windows.Controls.CheckBox
|
||||||
|
$checkbox.Content = $label
|
||||||
|
$checkbox.Tag = $setting.Name
|
||||||
|
if ($featureCheckboxStyle) {
|
||||||
|
$checkbox.Style = $featureCheckboxStyle
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$checkbox.Foreground = $revertWindow.FindResource('FgColor')
|
||||||
|
}
|
||||||
|
$checkbox.Margin = [System.Windows.Thickness]::new(0, 0, 0, 3)
|
||||||
|
$checkbox.IsEnabled = $canUndo
|
||||||
|
|
||||||
|
$undoText = New-Object System.Windows.Controls.TextBlock
|
||||||
|
$undoText.Text = if ($canUndo) { "Revert to: $undoLabel" } else { 'Revert not supported for this setting' }
|
||||||
|
$undoText.Style = $revertWindow.FindResource('RevertItemUndoTextStyle')
|
||||||
|
$undoText.Opacity = if ($canUndo) { 0.75 } else { 0.4 }
|
||||||
|
|
||||||
|
$row.Children.Add($checkbox) | Out-Null
|
||||||
|
$row.Children.Add($undoText) | Out-Null
|
||||||
|
$itemBorder.Child = $row
|
||||||
|
|
||||||
|
$itemsPanel.Children.Add($itemBorder) | Out-Null
|
||||||
|
$entryCheckboxes += $checkbox
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the divider from the last entry for cleaner list termination.
|
||||||
|
if ($itemsPanel.Children.Count -gt 0) {
|
||||||
|
$lastItem = $itemsPanel.Children[$itemsPanel.Children.Count - 1]
|
||||||
|
if ($lastItem -is [System.Windows.Controls.Border]) {
|
||||||
|
$lastItem.BorderThickness = [System.Windows.Thickness]::new(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entryCheckboxes.Count -eq 0) {
|
||||||
|
$emptyText = New-Object System.Windows.Controls.TextBlock
|
||||||
|
$emptyText.Text = 'No previously applied tweaks can be reverted'
|
||||||
|
$emptyText.Style = $revertWindow.FindResource('RevertEmptyTextStyle')
|
||||||
|
$itemsPanel.Children.Add($emptyText) | Out-Null
|
||||||
|
$selectAllBtn.IsEnabled = $false
|
||||||
|
$clearBtn.IsEnabled = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
$updateState = {
|
||||||
|
$selectedCount = 0
|
||||||
|
foreach ($cb in $entryCheckboxes) {
|
||||||
|
if ($cb.IsEnabled -and $cb.IsChecked -eq $true) {
|
||||||
|
$selectedCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$countText.Text = "$selectedCount settings selected"
|
||||||
|
$applyBtn.IsEnabled = ($selectedCount -gt 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($cb in $entryCheckboxes) {
|
||||||
|
$cb.Add_Checked($updateState)
|
||||||
|
$cb.Add_Unchecked($updateState)
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectAllBtn.Add_Click({
|
||||||
|
foreach ($cb in $entryCheckboxes) {
|
||||||
|
if ($cb.IsEnabled) {
|
||||||
|
$cb.IsChecked = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$clearBtn.Add_Click({
|
||||||
|
foreach ($cb in $entryCheckboxes) {
|
||||||
|
if ($cb.IsEnabled) {
|
||||||
|
$cb.IsChecked = $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$cancelHandler = {
|
||||||
|
$revertWindow.Tag = [PSCustomObject]@{
|
||||||
|
SelectedFeatureIds = @()
|
||||||
|
RestartExplorer = ($restartExplorerCheckbox -and $restartExplorerCheckbox.IsChecked -eq $true)
|
||||||
|
}
|
||||||
|
$revertWindow.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
$cancelBtn.Add_Click($cancelHandler)
|
||||||
|
|
||||||
|
$applyBtn.Add_Click({
|
||||||
|
$selected = @()
|
||||||
|
foreach ($cb in $entryCheckboxes) {
|
||||||
|
if ($cb.IsEnabled -and $cb.IsChecked -eq $true -and $cb.Tag) {
|
||||||
|
$selected += $cb.Tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$revertWindow.Tag = [PSCustomObject]@{
|
||||||
|
SelectedFeatureIds = $selected
|
||||||
|
RestartExplorer = ($restartExplorerCheckbox -and $restartExplorerCheckbox.IsChecked -eq $true)
|
||||||
|
}
|
||||||
|
$revertWindow.Close()
|
||||||
|
})
|
||||||
|
|
||||||
|
& $updateState
|
||||||
|
|
||||||
|
$revertWindow.ShowDialog() | Out-Null
|
||||||
|
|
||||||
|
if ($overlay -and -not $overlayWasAlreadyVisible) {
|
||||||
|
try {
|
||||||
|
$ownerWindow.Dispatcher.Invoke([action]{ $overlay.Visibility = 'Collapsed' })
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($revertWindow.Tag) {
|
||||||
|
return $revertWindow.Tag
|
||||||
|
}
|
||||||
|
|
||||||
|
return [PSCustomObject]@{
|
||||||
|
SelectedFeatureIds = @()
|
||||||
|
RestartExplorer = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
param (
|
param (
|
||||||
[switch]$CLI,
|
[switch]$CLI,
|
||||||
[switch]$Silent,
|
[switch]$Silent,
|
||||||
|
[switch]$Undo,
|
||||||
[switch]$Verbose,
|
[switch]$Verbose,
|
||||||
[switch]$Sysprep,
|
[switch]$Sysprep,
|
||||||
[string]$LogPath,
|
[string]$LogPath,
|
||||||
|
|||||||
17
Scripts/Helpers/GetUndoFeatureForParam.ps1
Normal file
17
Scripts/Helpers/GetUndoFeatureForParam.ps1
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Returns the feature metadata for a parameter when it supports undo; otherwise returns $null.
|
||||||
|
function GetUndoFeatureForParam {
|
||||||
|
param (
|
||||||
|
[string]$paramKey
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not $script:Features -or -not $script:Features.ContainsKey($paramKey)) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$feature = $script:Features[$paramKey]
|
||||||
|
if (-not ($feature.RegistryUndoKey -and $feature.UndoAction)) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
return $feature
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
param (
|
param (
|
||||||
[switch]$CLI,
|
[switch]$CLI,
|
||||||
[switch]$Silent,
|
[switch]$Silent,
|
||||||
|
[switch]$Undo,
|
||||||
[switch]$Sysprep,
|
[switch]$Sysprep,
|
||||||
[string]$LogPath,
|
[string]$LogPath,
|
||||||
[string]$User,
|
[string]$User,
|
||||||
@@ -117,11 +118,12 @@ $script:MainWindowSchema = "$PSScriptRoot/Schemas/MainWindow.xaml"
|
|||||||
$script:MessageBoxSchema = "$PSScriptRoot/Schemas/MessageBoxWindow.xaml"
|
$script:MessageBoxSchema = "$PSScriptRoot/Schemas/MessageBoxWindow.xaml"
|
||||||
$script:AboutWindowSchema = "$PSScriptRoot/Schemas/AboutWindow.xaml"
|
$script:AboutWindowSchema = "$PSScriptRoot/Schemas/AboutWindow.xaml"
|
||||||
$script:ApplyChangesWindowSchema = "$PSScriptRoot/Schemas/ApplyChangesWindow.xaml"
|
$script:ApplyChangesWindowSchema = "$PSScriptRoot/Schemas/ApplyChangesWindow.xaml"
|
||||||
|
$script:RevertSettingsWindowSchema = "$PSScriptRoot/Schemas/RevertSettingsWindow.xaml"
|
||||||
$script:SharedStylesSchema = "$PSScriptRoot/Schemas/SharedStyles.xaml"
|
$script:SharedStylesSchema = "$PSScriptRoot/Schemas/SharedStyles.xaml"
|
||||||
$script:BubbleHintSchema = "$PSScriptRoot/Schemas/BubbleHint.xaml"
|
$script:BubbleHintSchema = "$PSScriptRoot/Schemas/BubbleHint.xaml"
|
||||||
$script:LoadAppsDetailsScriptPath = "$PSScriptRoot/Scripts/FileIO/LoadAppsDetailsFromJson.ps1"
|
$script:LoadAppsDetailsScriptPath = "$PSScriptRoot/Scripts/FileIO/LoadAppsDetailsFromJson.ps1"
|
||||||
|
|
||||||
$script:ControlParams = 'WhatIf', 'Confirm', 'Verbose', 'Debug', 'LogPath', 'Silent', 'Sysprep', 'User', 'NoRestartExplorer', 'RunDefaults', 'RunDefaultsLite', 'RunSavedSettings', 'RunAppsListGenerator', 'CLI', 'AppRemovalTarget'
|
$script:ControlParams = 'WhatIf', 'Confirm', 'Verbose', 'Debug', 'LogPath', 'Silent', 'Undo', 'Sysprep', 'User', 'NoRestartExplorer', 'RunDefaults', 'RunDefaultsLite', 'RunSavedSettings', 'RunAppsListGenerator', 'CLI', 'AppRemovalTarget'
|
||||||
|
|
||||||
# Script-level variables for GUI elements
|
# Script-level variables for GUI elements
|
||||||
$script:GuiWindow = $null
|
$script:GuiWindow = $null
|
||||||
@@ -168,9 +170,23 @@ else {
|
|||||||
Start-Transcript -Path $script:DefaultLogPath -Append -IncludeInvocationHeader -Force | Out-Null
|
Start-Transcript -Path $script:DefaultLogPath -Append -IncludeInvocationHeader -Force | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if script has all required files
|
# Check if script has all required files/directories.
|
||||||
if (-not ((Test-Path $script:DefaultSettingsFilePath) -and (Test-Path $script:AppsListFilePath) -and (Test-Path $script:RegfilesPath) -and (Test-Path $script:AssetsPath) -and (Test-Path $script:AppSelectionSchema) -and (Test-Path $script:ApplyChangesWindowSchema) -and (Test-Path $script:SharedStylesSchema) -and (Test-Path $script:BubbleHintSchema) -and (Test-Path $script:FeaturesFilePath))) {
|
$optionalPathVariables = @('SavedSettingsFilePath', 'CustomAppsListFilePath', 'DefaultLogPath')
|
||||||
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present"
|
$requiredPathVariables = @(Get-Variable -Scope Script | Where-Object {
|
||||||
|
$_.Name -match '(FilePath|Schema|ScriptPath)$' -and ($optionalPathVariables -notcontains $_.Name)
|
||||||
|
} | Select-Object -ExpandProperty Name)
|
||||||
|
|
||||||
|
$missingRequiredPaths = @()
|
||||||
|
foreach ($variableName in $requiredPathVariables) {
|
||||||
|
$pathValue = Get-Variable -Name $variableName -Scope Script -ValueOnly
|
||||||
|
|
||||||
|
if ([String]::IsNullOrWhiteSpace($pathValue) -or -not (Test-Path $pathValue)) {
|
||||||
|
$missingRequiredPaths += "$variableName => $pathValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($missingRequiredPaths.Count -gt 0) {
|
||||||
|
Write-Error "Win11Debloat is unable to find required files, please ensure all script files are present. Missing: $($missingRequiredPaths -join '; ')"
|
||||||
Write-Output ""
|
Write-Output ""
|
||||||
Write-Output "Press any key to exit..."
|
Write-Output "Press any key to exit..."
|
||||||
$null = [System.Console]::ReadKey()
|
$null = [System.Console]::ReadKey()
|
||||||
@@ -264,6 +280,7 @@ if (-not $script:WingetInstalled -and -not $Silent) {
|
|||||||
. "$PSScriptRoot/Scripts/GUI/ApplySettingsToUiControls.ps1"
|
. "$PSScriptRoot/Scripts/GUI/ApplySettingsToUiControls.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-MessageBox.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-MessageBox.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-ApplyModal.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-ApplyModal.ps1"
|
||||||
|
. "$PSScriptRoot/Scripts/GUI/Show-RevertSettingsModal.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-AppSelectionWindow.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-AppSelectionWindow.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-MainWindow.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-MainWindow.ps1"
|
||||||
. "$PSScriptRoot/Scripts/GUI/Show-AboutDialog.ps1"
|
. "$PSScriptRoot/Scripts/GUI/Show-AboutDialog.ps1"
|
||||||
@@ -276,6 +293,7 @@ if (-not $script:WingetInstalled -and -not $Silent) {
|
|||||||
. "$PSScriptRoot/Scripts/Helpers/GenerateAppsList.ps1"
|
. "$PSScriptRoot/Scripts/Helpers/GenerateAppsList.ps1"
|
||||||
. "$PSScriptRoot/Scripts/Helpers/GetFriendlyTargetUserName.ps1"
|
. "$PSScriptRoot/Scripts/Helpers/GetFriendlyTargetUserName.ps1"
|
||||||
. "$PSScriptRoot/Scripts/Helpers/GetTargetUserForAppRemoval.ps1"
|
. "$PSScriptRoot/Scripts/Helpers/GetTargetUserForAppRemoval.ps1"
|
||||||
|
. "$PSScriptRoot/Scripts/Helpers/GetUndoFeatureForParam.ps1"
|
||||||
. "$PSScriptRoot/Scripts/Helpers/GetUserDirectory.ps1"
|
. "$PSScriptRoot/Scripts/Helpers/GetUserDirectory.ps1"
|
||||||
. "$PSScriptRoot/Scripts/Helpers/GetUserName.ps1"
|
. "$PSScriptRoot/Scripts/Helpers/GetUserName.ps1"
|
||||||
. "$PSScriptRoot/Scripts/Helpers/TestIfUserIsLoggedIn.ps1"
|
. "$PSScriptRoot/Scripts/Helpers/TestIfUserIsLoggedIn.ps1"
|
||||||
@@ -316,6 +334,18 @@ foreach ($Param in $script:ControlParams) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Guard: Undo mode requires at least one actionable, non-control parameter.
|
||||||
|
if ($script:Params.ContainsKey('Undo')) {
|
||||||
|
$undoTargets = @($script:Params.Keys | Where-Object {
|
||||||
|
($script:ControlParams -notcontains $_) -and $_ -ne 'Apps' -and $_ -ne 'CreateRestorePoint'
|
||||||
|
})
|
||||||
|
|
||||||
|
if ($undoTargets.Count -eq 0) {
|
||||||
|
Write-Error "The -Undo parameter requires at least one setting/feature parameter to revert."
|
||||||
|
AwaitKeyToExit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Hide progress bars for app removal, as they block Win11Debloat's output
|
# Hide progress bars for app removal, as they block Win11Debloat's output
|
||||||
if (-not ($script:Params.ContainsKey("Verbose"))) {
|
if (-not ($script:Params.ContainsKey("Verbose"))) {
|
||||||
$ProgressPreference = 'SilentlyContinue'
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
@@ -396,7 +426,7 @@ if ((-not $script:Params.Count) -or $RunDefaults -or $RunDefaultsLite -or $RunSa
|
|||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Warning "Unable to load WPF GUI (not supported in this environment), falling back to CLI mode"
|
Write-Warning "Something went wrong while loading the graphical interface, falling back to CLI mode: $_"
|
||||||
if (-not $Silent) {
|
if (-not $Silent) {
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "Press any key to continue..."
|
Write-Host "Press any key to continue..."
|
||||||
|
|||||||
Reference in New Issue
Block a user