Skip to content

Commit

Permalink
New visuals and fluent design ✨ The Harden Windows Security module/ap…
Browse files Browse the repository at this point in the history
…p switches to .NET 9 (#570)

The Harden Windows Security now uses .NET 9 (PowerShell 7.5), that means:

New appearance that is modern, based on Windows 11 fluent design
Mica backdrop
Better and more modern code
Removal of all custom UI elements that belonged to the old WPF designs
Faster startup time
Support for light/dark theme in the OS
Support for accent colors in the OS
More accessible user experience
Plus so much more benefits

Removed features:

Custom background image.
The ability to set custom background image.
Since Mica design is used for the background, there is no longer the need to set a custom color or custom background image.


PowerShell 7.5 was released 3 days ago, but since the module will require it, I'm waiting for PowerShell 7.5's MSIX package to be made available as well, and a day after that, will be releasing the new Harden Windows Security module version 0.7.4. This gives users enough time to install the new PowerShell version and also allows the bootstrapper script to automatically install the PowerShell 7.5 using MSIX package for users who don't have it.

This process ensures no downtime is experienced by users, especially those who use the Harden Windows Security module in automated workflows.
  • Loading branch information
HotCakeX authored Jan 26, 2025
1 parent 99e37ac commit f42dd4f
Show file tree
Hide file tree
Showing 100 changed files with 1,957 additions and 4,948 deletions.
6 changes: 6 additions & 0 deletions Harden-Windows-Security Module/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1042,3 +1042,9 @@ dotnet_diagnostic.SYSLIB1054.severity = silent

# CA1060: Move P/Invokes to NativeMethods class
dotnet_diagnostic.CA1060.severity = error

# WPF0001: Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
dotnet_diagnostic.WPF0001.severity = silent

# IDE0330: Prefer 'System.Threading.Lock'
dotnet_diagnostic.IDE0330.severity = error
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.1" />
<PackageReference Include="System.Management" Version="9.0.1" />
<PackageReference Include="System.Management.Automation" Version="7.4.6" />
<PackageReference Include="System.Management.Automation" Version="7.5.0" />
</ItemGroup>

<ItemGroup>
Expand Down
11 changes: 0 additions & 11 deletions Harden-Windows-Security Module/Main files/.NETAssembliesToLoad.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
System
System.IO
System.Xml
System.Data
WindowsBase
System.Xaml
System.Linq
System.Memory
System.Console
System.Windows
System.Runtime
System.Net.Http
System.Xml.Linq
System.Security
PresentationCore
System.Text.Json
Expand All @@ -19,8 +14,6 @@ System.Threading
System.Management
System.ObjectModel
System.Collections
System.Net.Primitives
System.ComponentModel
PresentationFramework
System.IO.Compression
System.Security.Claims
Expand All @@ -30,7 +23,6 @@ System.Threading.Thread
System.Xml.ReaderWriter
System.DirectoryServices
Microsoft.Win32.Registry
System.Security.Principal
System.Diagnostics.Process
Microsoft.Win32.Primitives
System.Diagnostics.EventLog
Expand All @@ -40,13 +32,10 @@ System.IO.Compression.zipfile
System.Security.AccessControl
System.Collections.NonGeneric
System.Collections.Concurrent
System.Runtime.InteropServices
System.Windows.Controls.Ribbon
System.Text.RegularExpressions
System.Text.Encoding.Extensions
System.ComponentModel.Primitives
System.Security.Principal.Windows
System.Diagnostics.FileVersionInfo
System.ComponentModel.TypeConverter
Microsoft.Management.Infrastructure
System.DirectoryServices.AccountManagement
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class InvokeConfirmation
/// This method will perform the system compliance checking and verification
/// </summary>
/// <param name="Categories"></param>
public static void Invoke(string[] Categories)
public static void Invoke(string[]? Categories)
{
ControlledFolderAccessHandler.Start(true, false);

Expand Down

This file was deleted.

35 changes: 14 additions & 21 deletions Harden-Windows-Security Module/Main files/C#/GUI/ASRRules/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
Expand All @@ -28,28 +29,25 @@ private void ASRRulesView(object obj)

// if Admin privileges are not available, return and do not proceed any further
// Will prevent the page from being loaded since the CurrentView won't be set/changed
if (!UserPrivCheck.IsAdmin())
if (!Environment.IsPrivilegedProcess)
{
Logger.LogMessage("ASR Rules page can only be used when running the Harden Windows Security Application with Administrator privileges", LogTypeIntel.ErrorInteractionRequired);
return;
}

// Construct the file path for the ASRRules view XAML
string xamlPath = Path.Combine(GlobalVars.path, "Resources", "XAML", "ASRRules.xaml");

// Read the XAML content from the file
string xamlContent = File.ReadAllText(xamlPath);
string xamlContent = File.ReadAllText(Path.Combine(GlobalVars.path, "Resources", "XAML", "ASRRules.xaml"));

// Parse the XAML content to create a UserControl
GUIASRRules.View = (UserControl)XamlReader.Parse(xamlContent);
UserControl View = (UserControl)XamlReader.Parse(xamlContent);

// Find the Parent Grid
GUIASRRules.ParentGrid = (Grid)GUIASRRules.View.FindName("ParentGrid");
Grid? ParentGrid = (Grid)View.FindName("ParentGrid");

#region finding elements

Button RetrieveASRStatusButton = GUIASRRules.ParentGrid.FindName("RetrieveASRStatus") as Button ?? throw new InvalidOperationException("RetrieveASRStatus could not be found in the ASRRules view");
Button ApplyASRRulesButton = GUIASRRules.ParentGrid.FindName("ApplyASRRulesButton") as Button ?? throw new InvalidOperationException("ApplyASRRulesButton could not be found in the ASRRules view");
Button RetrieveASRStatusButton = (Button)ParentGrid.FindName("RetrieveASRStatus");
Button ApplyASRRulesButton = (Button)ParentGrid.FindName("ApplyASRRulesButton");

#endregion

Expand All @@ -68,9 +66,6 @@ void ProcessListViewItems(ListView listView)
// Find the StackPanel inside the ListViewItem
if (item.Content is StackPanel stackPanel)
{
// Find the Label inside the StackPanel
// Label label = stackPanel.Children.OfType<Label>().FirstOrDefault();

// Find the ComboBox inside the StackPanel
ComboBox? comboBox = stackPanel.Children.OfType<ComboBox>().FirstOrDefault();

Expand Down Expand Up @@ -148,7 +143,7 @@ string GetASRRuleConfig(string ASRRuleName, byte ComboBoxIndex)
Application.Current.Dispatcher.Invoke(() =>
{
// Get the ListViews
if (GUIASRRules.ParentGrid.FindName("ASRRuleSet1") is not ListView ASRRuleSet1 || GUIASRRules.ParentGrid.FindName("ASRRuleSet2") is not ListView ASRRuleSet2)
if (ParentGrid.FindName("ASRRuleSet1") is not ListView ASRRuleSet1 || ParentGrid.FindName("ASRRuleSet2") is not ListView ASRRuleSet2)
{
throw new InvalidOperationException("One of the ListViews in the ASRRules view XAML is empty.");
}
Expand All @@ -162,7 +157,7 @@ string GetASRRuleConfig(string ASRRuleName, byte ComboBoxIndex)
});

// Run the loop asynchronously in a different thread
await System.Threading.Tasks.Task.Run(() =>
await Task.Run(() =>
{

// if LGPO doesn't already exist in the working directory, then download it
Expand Down Expand Up @@ -245,8 +240,8 @@ await System.Threading.Tasks.Task.Run(() =>
Application.Current.Dispatcher.Invoke(() =>
{
// Get the ListViews
if (GUIASRRules.ParentGrid.FindName("ASRRuleSet1") is not ListView ASRRuleSet1 ||
GUIASRRules.ParentGrid.FindName("ASRRuleSet2") is not ListView ASRRuleSet2)
if (ParentGrid.FindName("ASRRuleSet1") is not ListView ASRRuleSet1 ||
ParentGrid.FindName("ASRRuleSet2") is not ListView ASRRuleSet2)
{
throw new InvalidOperationException("One of the ListViews in the ASRRules view XAML is empty.");
}
Expand All @@ -273,7 +268,7 @@ await System.Threading.Tasks.Task.Run(() =>
});

// Run the loop asynchronously in a different thread
await System.Threading.Tasks.Task.Run(() =>
await Task.Run(() =>
{

// Get the MSFT_MpPreference WMI results and save them to the global variable GlobalVars.MDAVPreferencesCurrent
Expand Down Expand Up @@ -346,16 +341,14 @@ await System.Threading.Tasks.Task.Run(() =>

// mark as activity completed
ActivityTracker.IsActive = false;

}
};


// Cache the view before setting it as the CurrentView
_viewCache["ASRRulesView"] = GUIASRRules.View;
_viewCache["ASRRulesView"] = View;

// Set the CurrentView to the ASRRules view
CurrentView = GUIASRRules.View;
CurrentView = View;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace HardenWindowsSecurity;

public static class GUIAppControlManager
internal static class GUIAppControlManager
{
internal static UserControl? View;

Expand All @@ -14,9 +14,7 @@ public static class GUIAppControlManager
internal static PackageManager packageMgr = new();

// Pattern for AppControl Manager version and architecture extraction from file path and download link URL
internal static readonly Regex regex = new(@"_(?<Version>\d+\.\d+\.\d+\.\d+)_(?<Architecture>x64|arm64)\.msix$",
RegexOptions.IgnoreCase | RegexOptions.Compiled
);
internal static readonly Regex regex = new(@"_(?<Version>\d+\.\d+\.\d+\.\d+)_(?<Architecture>x64|arm64)\.msix$", RegexOptions.IgnoreCase);

internal static readonly Uri AppUpdateDownloadLinkURL = new("https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/refs/heads/main/AppControl%20Manager/DownloadURL.txt");
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,14 @@ private void AppControlManagerView(object obj)

// if Admin privileges are not available, return and do not proceed any further
// Will prevent the page from being loaded since the CurrentView won't be set/changed
if (!UserPrivCheck.IsAdmin())
if (!Environment.IsPrivilegedProcess)
{
Logger.LogMessage("AppControl Manager section can only be used when running the Harden Windows Security Application with Administrator privileges", LogTypeIntel.ErrorInteractionRequired);
return;
}

// Construct the file path for the AppControlManager view XAML
string xamlPath = Path.Combine(GlobalVars.path, "Resources", "XAML", "AppControlManager.xaml");

// Read the XAML content from the file
string xamlContent = File.ReadAllText(xamlPath);
string xamlContent = File.ReadAllText(Path.Combine(GlobalVars.path, "Resources", "XAML", "AppControlManager.xaml"));

// Parse the XAML content to create a UserControl
GUIAppControlManager.View = (UserControl)XamlReader.Parse(xamlContent);
Expand All @@ -61,13 +58,13 @@ private void AppControlManagerView(object obj)
GUIAppControlManager.ParentGrid = (Grid)GUIAppControlManager.View.FindName("ParentGrid");

// Finding other elements
Button InstallAppControlManagerButton = GUIAppControlManager.ParentGrid.FindName("InstallAppControlManagerButton") as Button ?? throw new InvalidOperationException("InstallAppControlManagerButton could not be found in the AppControlManager view");
Button ViewDemoOnYouTubeButton = GUIAppControlManager.ParentGrid.FindName("ViewDemoOnYouTubeButton") as Button ?? throw new InvalidOperationException("ViewDemoOnYouTubeButton could not be found in the AppControlManager view");
Button AccessTheGuideOnGitHubButton = GUIAppControlManager.ParentGrid.FindName("AccessTheGuideOnGitHubButton") as Button ?? throw new InvalidOperationException("AccessTheGuideOnGitHubButton could not be found in the AppControlManager view");
Image ViewDemoOnYouTubeButtonIcon = GUIAppControlManager.ParentGrid.FindName("ViewDemoOnYouTubeButtonIcon") as Image ?? throw new InvalidOperationException("ViewDemoOnYouTubeButtonIcon could not be found in the AppControlManager view");
Image AccessTheGuideOnGitHubButtonIcon = GUIAppControlManager.ParentGrid.FindName("AccessTheGuideOnGitHubButtonIcon") as Image ?? throw new InvalidOperationException("AccessTheGuideOnGitHubButtonIcon could not be found in the AppControlManager view");
Image InstallAppControlManagerButtonIcon = GUIAppControlManager.ParentGrid.FindName("InstallAppControlManagerButtonIcon") as Image ?? throw new InvalidOperationException("InstallAppControlManagerButtonIcon could not be found in the AppControlManager view");
ProgressBar MainProgressBar = GUIAppControlManager.ParentGrid.FindName("MainProgressBar") as ProgressBar ?? throw new InvalidOperationException("MainProgressBar could not be found in the AppControlManager view");
Button InstallAppControlManagerButton = (Button)GUIAppControlManager.ParentGrid.FindName("InstallAppControlManagerButton");
Button ViewDemoOnYouTubeButton = (Button)GUIAppControlManager.ParentGrid.FindName("ViewDemoOnYouTubeButton");
Button AccessTheGuideOnGitHubButton = (Button)GUIAppControlManager.ParentGrid.FindName("AccessTheGuideOnGitHubButton");
Image ViewDemoOnYouTubeButtonIcon = (Image)GUIAppControlManager.ParentGrid.FindName("ViewDemoOnYouTubeButtonIcon");
Image AccessTheGuideOnGitHubButtonIcon = (Image)GUIAppControlManager.ParentGrid.FindName("AccessTheGuideOnGitHubButtonIcon");
Image InstallAppControlManagerButtonIcon = (Image)GUIAppControlManager.ParentGrid.FindName("InstallAppControlManagerButtonIcon");
ProgressBar MainProgressBar = (ProgressBar)GUIAppControlManager.ParentGrid.FindName("MainProgressBar");

#region Assigning icon images for the buttons

Expand Down Expand Up @@ -404,7 +401,6 @@ await Task.Run(() =>
});
};


AccessTheGuideOnGitHubButton.Click += (sender, e) =>
{
_ = Process.Start(new ProcessStartInfo
Expand All @@ -414,7 +410,6 @@ await Task.Run(() =>
});
};


// Cache the view before setting it as the CurrentView
_viewCache["AppControlManagerView"] = GUIAppControlManager.View;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace HardenWindowsSecurity;

public static class GUIBitLocker
internal static class GUIBitLocker
{
internal static UserControl? View;

Expand Down
Loading

0 comments on commit f42dd4f

Please sign in to comment.