From 6c0acbd886e2d52879db14306ae1915d1b70e22d Mon Sep 17 00:00:00 2001 From: NathanW Date: Thu, 17 Sep 2026 14:51:40 +0200 Subject: [PATCH 1/2] fix: improved regex that doesn't exclude other windows languages --- Services/PowerPlanService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/PowerPlanService.cs b/Services/PowerPlanService.cs index ebecf8c..bb5c071 100644 --- a/Services/PowerPlanService.cs +++ b/Services/PowerPlanService.cs @@ -16,7 +16,7 @@ public class PowerPlanService : IPowerPlanService private static readonly Lazy powerPlansPath = new(GetPowerPlansPath); private static readonly string powerCfgExecutablePath = Path.Combine(Environment.SystemDirectory, "powercfg.exe"); private static readonly TimeSpan powerCfgTimeout = TimeSpan.FromSeconds(20); - private static readonly Regex powerSchemeRegex = new(@"^Power Scheme GUID:\s*([0-9a-fA-F-]+)[ \t]+\((.*)\)[ \t]*(\*)?[ \t]*\r?$", RegexOptions.Multiline | RegexOptions.Compiled); + private static readonly Regex powerSchemeRegex = new(@"^.*?\b([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})[ \t]+\((.*)\)[ \t]*(\*)?[ \t]*\r?$", RegexOptions.Multiline | RegexOptions.Compiled); private static readonly Regex pathTraversalRegex = new(@"(^|[\\/])\.\.([\\/]|$)", RegexOptions.Compiled); private static string PowerPlansPath => powerPlansPath.Value; From 5970feb4f6d3cd4d6d6e86309e630976da470577 Mon Sep 17 00:00:00 2001 From: PrimeBuild-pc Date: Tue, 29 Sep 2026 21:34:55 +0200 Subject: [PATCH 2/2] test: cover localized power plan output --- .../PowerPlanServiceTests.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Tests/ThreadPilot.Core.Tests/PowerPlanServiceTests.cs b/Tests/ThreadPilot.Core.Tests/PowerPlanServiceTests.cs index 1ecb058..596adf5 100644 --- a/Tests/ThreadPilot.Core.Tests/PowerPlanServiceTests.cs +++ b/Tests/ThreadPilot.Core.Tests/PowerPlanServiceTests.cs @@ -74,6 +74,28 @@ public async Task GetPowerPlansAsync_ParsesActiveMarkerWithOnePowerCfgCall() Assert.Equal(new[] { "/list" }, Assert.Single(runner.Invocations).Arguments); } + [Fact] + public async Task GetPowerPlansAsync_ParsesLocalizedOutput() + { + const string activeGuid = "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"; + var runner = new RecordingProcessRunner + { + ResultFactory = _ => new ProcessRunResult( + 0, + "Modes de gestion de l’alimentation existants (* Actif)\n" + + "GUID du mode de gestion de l’alimentation : 381b4222-f694-41f0-9685-ff5bb260df2e (Utilisation normale)\n" + + $"GUID du mode de gestion de l’alimentation : {activeGuid} (Haute performance) *", + string.Empty), + }; + var service = CreateService(runner); + + var plans = await service.GetPowerPlansAsync(); + + Assert.Equal(2, plans.Count); + Assert.Equal("Haute performance", plans.Single(plan => plan.Guid == activeGuid).Name); + Assert.True(plans.Single(plan => plan.Guid == activeGuid).IsActive); + } + [Fact] public async Task SetActivePowerPlanByGuidAsync_SkipsChange_WhenAlreadyActive() {