Skip to content

Commit ec5c46e

Browse files
Adds support for Efficiency Mode in windows
The EfficiencyModeUtilities class is incorporated to manage the efficient mode of processes in Windows, allowing the QoS level and priority to be adjusted through native APIs. The Show and Hide methods of WindowExtensions now allow you to turn Efficiency Mode on or off when showing or hiding the window. The QualityOfServiceLevel enum is added and references are updated in NativeMethods.txt. Code readability and style are also improved.
1 parent c761bd8 commit ec5c46e

File tree

3 files changed

+612
-366
lines changed

3 files changed

+612
-366
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.Runtime.Versioning;
4+
using Windows.Win32;
5+
using Windows.Win32.System.Threading;
6+
7+
namespace WinUIEx;
8+
9+
/// <summary>
10+
/// Based on: <br/>
11+
/// <see href="https://devblogs.microsoft.com/performance-diagnostics/reduce-process-interference-with-task-manager-efficiency-mode"/> <br/>
12+
/// <see href="https://devblogs.microsoft.com/performance-diagnostics/introducing-ecoqos/"/> <br/>
13+
/// </summary>
14+
public static class EfficiencyModeUtilities
15+
{
16+
private static bool EnsureNonZero(this Windows.Win32.Foundation.BOOL value)
17+
{
18+
return value != 0;
19+
}
20+
21+
/// <summary>
22+
/// Based on <see href="https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessinformation"/>
23+
/// </summary>
24+
[SupportedOSPlatform("windows10.0.16299.0")]
25+
public static unsafe void SetProcessQualityOfServiceLevel(QualityOfServiceLevel level)
26+
{
27+
PROCESS_POWER_THROTTLING_STATE powerThrottling = new()
28+
{
29+
Version = PInvoke.PROCESS_POWER_THROTTLING_CURRENT_VERSION
30+
};
31+
32+
switch (level)
33+
{
34+
case QualityOfServiceLevel.Default:
35+
powerThrottling.ControlMask = 0;
36+
powerThrottling.StateMask = 0;
37+
break;
38+
39+
case QualityOfServiceLevel.Eco when Environment.OSVersion.Version >= new Version(11, 0):
40+
case QualityOfServiceLevel.Low:
41+
powerThrottling.ControlMask = PInvoke.PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
42+
powerThrottling.StateMask = PInvoke.PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
43+
break;
44+
45+
case QualityOfServiceLevel.High:
46+
powerThrottling.ControlMask = PInvoke.PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
47+
powerThrottling.StateMask = 0;
48+
break;
49+
50+
default:
51+
throw new NotImplementedException();
52+
}
53+
54+
_ = PInvoke.SetProcessInformation(
55+
hProcess: PInvoke.GetCurrentProcess(),
56+
ProcessInformationClass: PROCESS_INFORMATION_CLASS.ProcessPowerThrottling,
57+
ProcessInformation: &powerThrottling,
58+
ProcessInformationSize: (uint)sizeof(PROCESS_POWER_THROTTLING_STATE)).EnsureNonZero();
59+
}
60+
61+
/// <summary>
62+
/// Based on <see href="https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass"/>
63+
/// </summary>
64+
[SupportedOSPlatform("windows5.1.2600")]
65+
public static unsafe void SetProcessPriorityClass(ProcessPriorityClass priorityClass)
66+
{
67+
PROCESS_CREATION_FLAGS flags = priorityClass switch
68+
{
69+
ProcessPriorityClass.Idle => PROCESS_CREATION_FLAGS.IDLE_PRIORITY_CLASS,
70+
ProcessPriorityClass.BelowNormal => PROCESS_CREATION_FLAGS.BELOW_NORMAL_PRIORITY_CLASS,
71+
ProcessPriorityClass.Normal => PROCESS_CREATION_FLAGS.NORMAL_PRIORITY_CLASS,
72+
ProcessPriorityClass.AboveNormal => PROCESS_CREATION_FLAGS.ABOVE_NORMAL_PRIORITY_CLASS,
73+
ProcessPriorityClass.High => PROCESS_CREATION_FLAGS.HIGH_PRIORITY_CLASS,
74+
ProcessPriorityClass.RealTime => PROCESS_CREATION_FLAGS.REALTIME_PRIORITY_CLASS,
75+
_ => throw new NotImplementedException(),
76+
};
77+
78+
_ = PInvoke.SetPriorityClass(
79+
hProcess: PInvoke.GetCurrentProcess(),
80+
dwPriorityClass: flags).EnsureNonZero();
81+
}
82+
83+
/// <summary>
84+
/// Enables/disables efficient mode for process <br/>
85+
/// Based on: <see href="https://devblogs.microsoft.com/performance-diagnostics/reduce-process-interference-with-task-manager-efficiency-mode/"/>
86+
/// </summary>
87+
/// <param name="value"></param>
88+
[SupportedOSPlatform("windows10.0.16299.0")]
89+
public static void SetEfficiencyMode(bool value)
90+
{
91+
QualityOfServiceLevel ecoLevel = Environment.OSVersion.Version >= new Version(11, 0) ? QualityOfServiceLevel.Eco : QualityOfServiceLevel.Low;
92+
93+
SetProcessQualityOfServiceLevel(value
94+
? ecoLevel
95+
: QualityOfServiceLevel.Default);
96+
SetProcessPriorityClass(value
97+
? ProcessPriorityClass.Idle
98+
: ProcessPriorityClass.Normal);
99+
}
100+
}
101+
102+
/// <summary>
103+
/// Specifies the Quality of Service (QoS) levels for process power management.
104+
/// These levels guide the Windows scheduler in balancing performance and energy efficiency.
105+
/// </summary>
106+
public enum QualityOfServiceLevel
107+
{
108+
/// <summary>
109+
/// Let the operating system manage power throttling automatically.
110+
/// No specific execution speed constraints are applied by the application.
111+
/// </summary>
112+
Default,
113+
114+
/// <summary>
115+
/// EcoQoS level. The most efficient power level available (Windows 11 and later).
116+
/// Prioritizes efficiency cores (E-cores) and significantly reduces CPU clock speed
117+
/// to minimize thermal footprint and power consumption.
118+
/// </summary>
119+
Eco,
120+
121+
/// <summary>
122+
/// Low-priority power level. Similar to standard power throttling in earlier Windows 10 versions.
123+
/// Intended for background tasks where latency and high execution speed are not critical.
124+
/// </summary>
125+
Low,
126+
127+
/// <summary>
128+
/// High-performance level. Explicitly disables execution speed throttling mechanisms
129+
/// to ensure the process has maximum access to CPU resources.
130+
/// </summary>
131+
High
132+
}

src/WinUIEx/NativeMethods.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,11 @@ CreatePolygonRgn
7474
CombineRgn
7575
SetWindowRgn
7676
GetWindowRgn
77-
GetWindowRgnBox
77+
GetWindowRgnBox
78+
SetProcessInformation
79+
PROCESS_INFORMATION_CLASS
80+
PROCESS_POWER_THROTTLING_STATE
81+
PROCESS_POWER_THROTTLING_CURRENT_VERSION
82+
PROCESS_POWER_THROTTLING_EXECUTION_SPEED
83+
GetCurrentProcess
84+
SetPriorityClass

0 commit comments

Comments
 (0)