src/modules/awake/README.md
A PowerToys utility that prevents Windows from sleeping and/or turning off the display.
Author: Den Delimarsky
The Awake module consists of three projects:
| Project | Purpose |
|---|---|
Awake/ | Main WinExe application with CLI support |
Awake.ModuleServices/ | Service layer for PowerToys integration |
AwakeModuleInterface/ | C++ native module bridge |
The module uses the Win32 SetThreadExecutionState() API to signal Windows that the system should remain awake:
ES_SYSTEM_REQUIRED - Prevents system sleepES_DISPLAY_REQUIRED - Prevents display sleepES_CONTINUOUS - Maintains state until explicitly changed| Mode | Description |
|---|---|
| PASSIVE | Normal power behavior (off) |
| INDEFINITE | Keep awake until manually stopped |
| TIMED | Keep awake for a specified duration |
| EXPIRABLE | Keep awake until a specific date/time |
Awake can be run standalone with the following options:
PowerToys.Awake.exe [options]
Options:
-c, --use-pt-config Use PowerToys configuration file
-d, --display-on Keep display on (default: false)
-t, --time-limit Time limit in seconds
-p, --pid Process ID to bind to
-e, --expire-at Expiration date/time
-u, --use-parent-pid Bind to parent process
Keep system awake indefinitely:
PowerToys.Awake.exe
Keep awake for 1 hour with display on:
PowerToys.Awake.exe --time-limit 3600 --display-on
Keep awake until a specific time:
PowerToys.Awake.exe --expire-at "2024-12-31 23:59:59"
Keep awake while another process is running:
PowerToys.Awake.exe --pid 1234
Pure Win32 API for Tray UI - No WPF/WinForms dependencies, keeping the binary small. Uses direct Shell_NotifyIcon API for tray icon management.
Reactive Extensions (Rx.NET) - Used for timed operations via Observable.Interval() and Observable.Timer(). File system watching uses 25ms throttle to debounce rapid config changes.
Custom SynchronizationContext - Queue-based message dispatch ensures tray operations run on a dedicated thread for thread-safe UI updates.
Dual-Mode Operation
Process Binding - The --pid parameter keeps the system awake only while a target process runs, with auto-exit when the parent PowerToys runner terminates.
| File | Purpose |
|---|---|
Program.cs | Entry point & CLI parsing |
Core/Manager.cs | State orchestration & power management |
Core/TrayHelper.cs | System tray UI management |
Core/Native/Bridge.cs | Win32 P/Invoke declarations |
Core/Threading/SingleThreadSynchronizationContext.cs | Threading utilities |
From the src/modules/awake directory:
# Using the build script
.\scripts\Build-Awake.ps1
# Or with specific configuration
.\scripts\Build-Awake.ps1 -Configuration Debug -Platform x64
Or using MSBuild directly:
msbuild Awake\Awake.csproj /p:Configuration=Release /p:Platform=x64
When running with PowerToys (--use-pt-config), settings are stored in:
%LOCALAPPDATA%\Microsoft\PowerToys\Awake\settings.json
When "Keep display on" is enabled, Awake uses the ES_DISPLAY_REQUIRED flag which blocks Windows Task Scheduler from detecting the system as idle. This prevents scheduled maintenance tasks (like SSD TRIM, disk defragmentation, and other idle-triggered tasks) from running.
Per Microsoft's documentation:
"An exception would be for any presentation type application that sets the ES_DISPLAY_REQUIRED flag. This flag forces Task Scheduler to not consider the system as being idle, regardless of user activity or resource consumption."
Workarounds:
Disable "Keep display on" - With this setting off, Awake only uses ES_SYSTEM_REQUIRED which still prevents sleep but allows Task Scheduler to detect idle state.
Manually run maintenance tasks - For example, to run TRIM manually:
# Run as Administrator
Optimize-Volume -DriveLetter C -ReTrim -Verbose
The module emits telemetry events for:
Microsoft.PowerToys.Telemetry