diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f2a1dd..a55adbb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,12 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [1.20.41] - 2026-06-17
+
+### Fixed
+- **"Restore All" in Performance Mode now fully clears the saved baseline.** After restoring everything to the original state, the on-disk snapshot was left behind, so the next change reloaded the now-reverted values as its baseline — a later "Restore All" could then re-apply stale settings. The saved snapshot is now deleted when you restore all.
+- **Applying several performance tweaks at once can no longer race the baseline capture.** The independent Apply buttons (power plan, visual effects, Game Mode, Xbox Game Bar, GPU, processor state) each captured the "before" snapshot without coordination, so two run together could both think no baseline existed. Baseline capture is now serialized so the original state is recorded exactly once.
+
## [1.20.40] - 2026-06-17
### Fixed
diff --git a/SysManager/SysManager/Services/PerformanceService.cs b/SysManager/SysManager/Services/PerformanceService.cs
index 22e428c..4805769 100644
--- a/SysManager/SysManager/Services/PerformanceService.cs
+++ b/SysManager/SysManager/Services/PerformanceService.cs
@@ -121,6 +121,22 @@ public static void SaveSnapshot(OriginalSnapshot snapshot)
catch (UnauthorizedAccessException ex) { Log.Warning(ex, "Failed to save performance snapshot"); }
}
+ ///
+ /// Delete the persisted snapshot from disk. Called after "Restore All" so the next
+ /// Apply captures a fresh baseline instead of reloading the now-reverted pre-restore
+ /// state via .
+ ///
+ public static void DeleteSnapshot()
+ {
+ try
+ {
+ if (File.Exists(SnapshotPath)) File.Delete(SnapshotPath);
+ Log.Information("Performance snapshot deleted from {Path}", SnapshotPath);
+ }
+ catch (IOException ex) { Log.Warning(ex, "Failed to delete performance snapshot"); }
+ catch (UnauthorizedAccessException ex) { Log.Warning(ex, "Failed to delete performance snapshot"); }
+ }
+
/// Load a previously saved snapshot from disk. Returns null if none exists.
public static OriginalSnapshot? LoadSnapshot()
{
diff --git a/SysManager/SysManager/SysManager.csproj b/SysManager/SysManager/SysManager.csproj
index ed6cb9b..91cba23 100644
--- a/SysManager/SysManager/SysManager.csproj
+++ b/SysManager/SysManager/SysManager.csproj
@@ -10,9 +10,9 @@
SysManager
true
NU1603;NU1701
- 1.20.40
- 1.20.40.0
- 1.20.40.0
+ 1.20.41
+ 1.20.41.0
+ 1.20.41.0
SysManager
SysManager — Windows system monitoring toolkit by laurentiu021. Network, updates, health, logs, safe deep cleanup.
https://github.com/laurentiu021/SystemManager
diff --git a/SysManager/SysManager/ViewModels/PerformanceViewModel.cs b/SysManager/SysManager/ViewModels/PerformanceViewModel.cs
index 907b534..fbeedf9 100644
--- a/SysManager/SysManager/ViewModels/PerformanceViewModel.cs
+++ b/SysManager/SysManager/ViewModels/PerformanceViewModel.cs
@@ -27,6 +27,9 @@ public sealed partial class PerformanceViewModel : ViewModelBase
{
private readonly PerformanceService _service;
private PerformanceService.OriginalSnapshot? _snapshot;
+ // Serializes the load-modify of _snapshot so two Apply commands running at once
+ // can't both observe a null snapshot and race the capture/save.
+ private readonly SemaphoreSlim _snapshotGate = new(1, 1);
[ObservableProperty] private bool _isElevated;
[ObservableProperty] private PerformanceProfile _profile = new();
@@ -71,10 +74,15 @@ private async Task InitAsync()
/// Ensure snapshot exists before any change.
private async Task EnsureSnapshotAsync()
{
- _snapshot ??= PerformanceService.LoadSnapshot()
- ?? await _service.TakeSnapshotAsync();
- PerformanceService.SaveSnapshot(_snapshot);
- HasSnapshot = true;
+ await _snapshotGate.WaitAsync().ConfigureAwait(false);
+ try
+ {
+ _snapshot ??= PerformanceService.LoadSnapshot()
+ ?? await _service.TakeSnapshotAsync();
+ PerformanceService.SaveSnapshot(_snapshot);
+ HasSnapshot = true;
+ }
+ finally { _snapshotGate.Release(); }
}
private void UpdateSummary()
@@ -508,6 +516,10 @@ private async Task RestoreAllAsync()
Log.Information("Performance settings restored to original snapshot");
_snapshot = null;
HasSnapshot = false;
+ // Delete the persisted snapshot too — otherwise the next Apply reloads the
+ // now-reverted pre-restore baseline via LoadSnapshot and a later Restore All
+ // would re-apply stale values.
+ PerformanceService.DeleteSnapshot();
await RefreshAsync();
}
catch (InvalidOperationException ex) { StatusMessage = $"Restore all settings failed: {ex.Message}"; }
@@ -561,6 +573,7 @@ protected override void Dispose(bool disposing)
if (disposing)
{
_snapshot = null;
+ _snapshotGate.Dispose();
}
base.Dispose(disposing);
}