Files
PowerToys/doc/devdocs/core/runner.md
Gleb Khmyznikov 9ee9ad3fa6 initial
2025-06-13 16:10:31 +02:00

6.4 KiB

PowerToys Runner

The PowerToys Runner is the main executable (PowerToys.exe) that loads and manages all PowerToys modules.

Runner Architecture

The Runner is responsible for:

  • Managing the tray icon
  • Loading and managing module interfaces
  • Handling enabling/disabling modules
  • Processing global hotkeys
  • Managing updates and settings

Key Components

  • Main CPP file manages the tray icon and modules
  • Creates a list of modules with DLL paths
  • Special handling for WinUI 3 apps (separated in different folder)
  • DLLs flattening for consistent versions
  • Runs as part of the Windows message loop
  • Creates a window handle with a specific class name
  • Registers itself as the window handler for components requiring a window handler

Process Flow

  1. Initialize logger
  2. Create single instance application mutex
  3. Initialize common utility code
  4. Parse command line arguments
  5. Start the tray icon
  6. Initialize low-level keyboard hooks
  7. Load module interfaces from DLLs
  8. Start enabled modules
  9. Enter Windows message loop
  10. On exit, stop modules and clean up resources

System Tray Icon Implementation

The system tray icon is one of the first components that starts when calling the render_main function:

  • Defined in tray_icon.h and tray_icon.cpp
  • Creates a popup window and registers as window handler via start_tray_icon()
  • Processes window messages through tray_icon_window_proc()
  • Uses WM_COMMAND and tray icon notifications for handling menu options
  • Handles left mouse clicks (distinguishes between single and double clicks)
  • Monitors taskbar creation to re-register the icon if needed
  • Uses shell_notify_icon to register with the system tray

Tray Icon Menu

  • Menus are defined in .RC files (Resource files)
  • base.h defines IDs
  • resources.resx contains localized strings
  • The tray icon window proc handles showing the popup menu

Centralized Keyboard Hook

  • Located in "centralized_keyboard_hook.cpp"
  • Handles hotkeys for multiple modules to prevent performance issues
  • Contains optimizations to exit early when possible:
    • Ignores keystrokes generated by PowerToys itself
    • Ignores when no keys are actually pressed
    • Uses metadata to avoid re-processing modified inputs
  • Performance consideration: handler must run very fast as it's called on every keystroke

Module Loading Process

  1. Scan module directory for DLLs
  2. Create the module interface object for each module
  3. Load settings for each module
  4. Initialize each module
  5. Check GPO policies to determine which modules can start
  6. Start enabled modules that aren't disabled by policy

Finding and Messaging the Tray Icon

The tray icon class is used when sending messages to the runner. For example, to close the runner:

// Find the window with the PowerToys tray icon class and send it a close message
WM_CLOSE

Key Files and Their Purposes

main.cpp

Contains the executable starting point, initialization code and the list of known PowerToys. All singletons are also initialized here at the start. Loads all the powertoys by scanning the ./modules folder and enable()s those marked as enabled in %LOCALAPPDATA%\Microsoft\PowerToys\settings.json config. Then it runs a message loop for the tray UI. Note that this message loop also handles lowlevel_keyboard_hook events.

powertoy_module.h and powertoy_module.cpp

Contains code for initializing and managing the PowerToy modules. PowertoyModule is a RAII-style holder for the PowertoyModuleIface pointer, which we got by invoking module DLL's powertoy_create function.

tray_icon.cpp

Contains code for managing the PowerToys tray icon and its menu commands. Note that dispatch_run_on_main_ui_thread is used to transfer received json message from the Settings window to the main thread, since we're communicating with it from a dedicated thread.

settings_window.cpp

Contains code for starting the PowerToys settings window and communicating with it. Settings window is a separate process, so we're using Windows pipes as a transport for json messages.

general_settings.cpp

Contains code for loading, saving and applying the general settings.

auto_start_helper.cpp

Contains helper code for registering and unregistering PowerToys to run when the user logs in.

unhandled_exception_handler.cpp

Contains helper code to get stack traces in builds. Can be used by adding a call to init_global_error_handlers in WinMain.

trace.cpp

Contains code for telemetry.

svgs

Contains the SVG assets used by the PowerToys modules.

bug_report.cpp

Contains logic to start bug report tool.

centralized_hotkeys.cpp

Contains hot key logic registration and un-registration.

centralized_kb_hook.cpp

Contains logic to handle PowerToys' keyboard shortcut functionality.

restart_elevated.cpp

Contains logic for restarting the current process with different elevation levels.

RestartManagement.cpp

Contains code for restarting a process.

settings_telemetry.cpp

Contains logic that periodically triggers module-specific setting's telemetry delivery and manages timing and error handling for the process.

UpdateUtils.cpp

Contains code to handle the automatic update checking, notification, and installation process for PowerToys.