Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Windows toast notifications when RAM > 90%, uptime > 14 days, or disk
health degrades. Right-click context menu with Show / Exit. Uses
H.NotifyIcon.Wpf 2.2.1. Closes #262.
- **About — Changelog link** — new "View Changelog" button opens the
GitHub CHANGELOG.md in the browser. Closes #232.
- **Drivers — Hide system drivers** — toggle to filter out Microsoft /
Windows drivers from the list, showing only third-party drivers.
Closes #234.
- **Startup Manager — Hide Windows entries** — toggle to filter out
Microsoft / Windows startup items that should not be disabled.
Closes #238.
- **IntGreaterThanZeroConverter** — value converter for conditional
visibility when an integer is greater than zero.
- **IDialogService** — abstraction for user confirmation dialogs, replacing
Expand Down
3 changes: 3 additions & 0 deletions SysManager/SysManager/ViewModels/AboutViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ private void OpenManualDownload()
[RelayCommand]
private void OpenRepo() => OpenUrl($"https://github.com/{UpdateService.Owner}/{UpdateService.Repo}");

[RelayCommand]
private void OpenChangelog() => OpenUrl($"https://github.com/{UpdateService.Owner}/{UpdateService.Repo}/blob/main/CHANGELOG.md");

[RelayCommand]
private void OpenLicense() => OpenUrl($"https://github.com/{UpdateService.Owner}/{UpdateService.Repo}/blob/main/LICENSE");

Expand Down
33 changes: 30 additions & 3 deletions SysManager/SysManager/ViewModels/DriversViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,29 @@ public partial class DriversViewModel : ViewModelBase
{
private readonly PowerShellRunner _runner;
private CancellationTokenSource? _cts;
private readonly List<DriverEntry> _allDrivers = new();

public ObservableCollection<DriverEntry> Drivers { get; } = new();

[ObservableProperty] private int _driverCount;
[ObservableProperty] private string _summary = "Click List drivers to scan installed drivers.";
[ObservableProperty] private bool _hideSystemDrivers;

public DriversViewModel(PowerShellRunner runner)
{
_runner = runner;
}

partial void OnHideSystemDriversChanged(bool value) => ApplyFilter();

[RelayCommand]
private async Task ListDriversAsync()
{
IsBusy = true;
IsProgressIndeterminate = true;
StatusMessage = "Scanning installed drivers…";
Drivers.Clear();
_allDrivers.Clear();
_cts?.Dispose();
_cts = new CancellationTokenSource();

Expand All @@ -60,8 +65,9 @@ await _runner.RunScriptViaPwshAsync(@"
finally { _runner.LineReceived -= Capture; }

ParseDriverJson(json.ToString());
DriverCount = Drivers.Count;
Summary = $"{DriverCount} drivers found.";
ApplyFilter();
Summary = $"{_allDrivers.Count} drivers found" +
(HideSystemDrivers ? $" ({DriverCount} shown, system drivers hidden)." : ".");
StatusMessage = "Done";
}
catch (OperationCanceledException) { StatusMessage = "Cancelled."; }
Expand Down Expand Up @@ -103,7 +109,7 @@ private void ParseDriverJson(string raw)
DriverDate = ParseCimDate(el.TryGetProperty("DriverDate", out var dd) ? dd : default),
}))
{
Drivers.Add(entry);
_allDrivers.Add(entry);
}
}
catch (JsonException ex)
Expand All @@ -113,6 +119,27 @@ private void ParseDriverJson(string raw)
}
}

private void ApplyFilter()
{
Drivers.Clear();
var filtered = HideSystemDrivers
? _allDrivers.Where(d => !IsSystemDriver(d))
: _allDrivers;

foreach (var d in filtered)
Drivers.Add(d);

DriverCount = Drivers.Count;
if (_allDrivers.Count > 0)
Summary = HideSystemDrivers
? $"{_allDrivers.Count} drivers found ({DriverCount} shown, system drivers hidden)."
: $"{_allDrivers.Count} drivers found.";
}

private static bool IsSystemDriver(DriverEntry d)
=> d.Manufacturer.Contains("Microsoft", StringComparison.OrdinalIgnoreCase) ||
d.Manufacturer.Contains("Windows", StringComparison.OrdinalIgnoreCase);

/// <summary>
/// CIM dates come as "/Date(ticks)/" strings in JSON.
/// </summary>
Expand Down
29 changes: 26 additions & 3 deletions SysManager/SysManager/ViewModels/StartupViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,23 @@ namespace SysManager.ViewModels;
public partial class StartupViewModel : ViewModelBase
{
private readonly StartupService _service = new();
private readonly List<StartupEntry> _allEntries = new();

public ObservableCollection<StartupEntry> Entries { get; } = new();

[ObservableProperty] private int _enabledCount;
[ObservableProperty] private int _disabledCount;
[ObservableProperty] private int _totalCount;
[ObservableProperty] private string _scanSummary = "Click Scan to discover startup items.";
[ObservableProperty] private bool _hideWindowsEntries;

public StartupViewModel()
{
_ = InitAsync();
}

partial void OnHideWindowsEntriesChanged(bool value) => ApplyFilter();

private async Task InitAsync()
{
try { await ScanAsync(); }
Expand All @@ -46,15 +50,16 @@ private async Task ScanAsync()
try
{
var items = await _service.ScanAsync();
_allEntries.Clear();
Entries.Clear();
foreach (var item in items.OrderBy(e => e.Name, StringComparer.OrdinalIgnoreCase))
{
item.Icon = IconExtractorService.GetIcon(item.Command);
Entries.Add(item);
_allEntries.Add(item);
}

UpdateCounts();
StatusMessage = $"Found {TotalCount} startup items.";
ApplyFilter();
StatusMessage = $"Found {_allEntries.Count} startup items.";
}
catch (InvalidOperationException ex)
{
Expand Down Expand Up @@ -132,4 +137,22 @@ private void UpdateCounts()
TotalCount = Entries.Count;
ScanSummary = $"{EnabledCount} enabled · {DisabledCount} disabled · {TotalCount} total";
}

private void ApplyFilter()
{
Entries.Clear();
var filtered = HideWindowsEntries
? _allEntries.Where(e => !IsWindowsEntry(e))
: _allEntries;

foreach (var item in filtered)
Entries.Add(item);

UpdateCounts();
}

private static bool IsWindowsEntry(StartupEntry entry)
=> entry.Publisher.Contains("Microsoft", StringComparison.OrdinalIgnoreCase) ||
entry.Command.Contains(@"\Windows\", StringComparison.OrdinalIgnoreCase) ||
entry.Command.Contains(@"\Microsoft\", StringComparison.OrdinalIgnoreCase);
}
Loading