# 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 Initialization and Message Processing - `start_tray_icon()` initializes the tray icon by: - Creating a window with the specified class name - Setting up the notification icon data structure (NOTIFYICONDATA) - Registering for taskbar recreate messages - Adding the icon to the system tray - `tray_icon_window_proc()` processes window messages, including: - Handling `wm_icon_notify` messages from tray icon interactions - Distinguishing between left-click, double-click, and right-click actions - Showing context menus or opening Settings windows based on interaction type ### Communication with Settings UI When the tray icon is clicked or a menu option is selected, the Runner communicates with the Settings UI: - For quick access flyout (left-click): ```cpp current_settings_ipc->send(L"{\"ShowYourself\":\"flyout\"}"); ``` - For the main dashboard (menu option or double-click): ```cpp current_settings_ipc->send(L"{\"ShowYourself\":\"Dashboard\"}"); ``` ### IPC Communication Mechanism - The Runner and Settings UI communicate through Windows Named Pipes - A two-way pipe (TwoWayPipeMessageIPC) is established between processes - JSON messages are sent through this pipe to control UI behavior - The Settings UI initializes the pipe connection on startup: ```csharp ipcmanager = new TwoWayPipeMessageIPCManaged(cmdArgs[(int)Arguments.SettingsPipeName], cmdArgs[(int)Arguments.PTPipeName], (string message) => { if (IPCMessageReceivedCallback != null && message.Length > 0) { IPCMessageReceivedCallback(message); } }); ``` ### Settings UI Message Processing The Settings UI processes incoming IPC messages through a callback chain: 1. Messages from the Runner are received through the IPC callback 2. Messages are parsed as JSON objects 3. Registered handlers in `ShellPage.ShellHandler.IPCResponseHandleList` process the messages 4. The `ReceiveMessage` method in `ShellPage` interprets commands: - For flyout display: `"ShowYourself": "flyout"` - For main window: `"ShowYourself": "Dashboard"` or other page names When showing the flyout, the tray icon can also send position coordinates to place the flyout near the tray icon: ```json { "ShowYourself": "flyout", "x_position": 1234, "y_position": 567 } ``` The flyout window is then activated and brought to the foreground using native Windows APIs to ensure visibility. ### 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: ```cpp // Find the window with the PowerToys tray icon class and send it a close message WM_CLOSE ``` ## Key Files and Their Purposes #### [`main.cpp`](/src/runner/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](https://learn.microsoft.com/windows/win32/winmsg/using-messages-and-message-queues) for the tray UI. Note that this message loop also [handles lowlevel_keyboard_hook events](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/lowlevel_keyboard_event.cpp#L24). #### [`powertoy_module.h`](/src/runner/powertoy_module.h) and [`powertoy_module.cpp`](/src/runner/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](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/powertoy_module.cpp#L13-L24). #### [`tray_icon.cpp`](/src/runner/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](/doc/devdocs/settings.md) to the main thread, since we're communicating with it from [a dedicated thread](https://github.com/microsoft/PowerToys/blob/7357e40d3f54de51176efe54fda6d57028837b8c/src/runner/settings_window.cpp#L267-L271). #### [`settings_window.cpp`](/src/runner/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](https://learn.microsoft.com/windows/win32/ipc/pipes) as a transport for json messages. #### [`general_settings.cpp`](/src/runner/general_settings.cpp) Contains code for loading, saving and applying the general settings. #### [`auto_start_helper.cpp`](/src/runner/auto_start_helper.cpp) Contains helper code for registering and unregistering PowerToys to run when the user logs in. #### [`unhandled_exception_handler.cpp`](/src/runner/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`](./main.cpp). #### [`trace.cpp`](/src/runner/trace.cpp) Contains code for telemetry. #### [`svgs`](/src/runner/svgs/) Contains the SVG assets used by the PowerToys modules. #### [`bug_report.cpp`](/src/runner/bug_report.cpp) Contains logic to start bug report tool. #### [`centralized_hotkeys.cpp`](/src/runner/centralized_hotkeys.cpp) Contains hot key logic registration and un-registration. #### [`centralized_kb_hook.cpp`](/src/runner/centralized_kb_hook.cpp) Contains logic to handle PowerToys' keyboard shortcut functionality. #### [`restart_elevated.cpp`](/src/runner/restart_elevated.cpp) Contains logic for restarting the current process with different elevation levels. #### [`RestartManagement.cpp`](/src/runner/RestartManagement.cpp) Contains code for restarting a process. #### [`settings_telemetry.cpp`](/src/runner/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`](/src/runner/UpdateUtils.cpp) Contains code to handle the automatic update checking, notification, and installation process for PowerToys.