Skip to main content

Overview

Every PowerToys module must implement the PowertoyModuleIface interface, which defines a standardized contract between the module and the Runner. This interface enables the Runner to load, configure, enable, disable, and communicate with modules in a consistent manner.

PowertoyModuleIface Definition

The module interface is defined in src/modules/interface/powertoy_module_interface.h:
Reference: src/modules/interface/powertoy_module_interface.h:37-171

Module Lifecycle

The Runner interacts with modules following this lifecycle:
Reference: src/modules/interface/powertoy_module_interface.h:6-35

Implementing a Simple Module

Here’s a complete example of a simple module implementation based on Find My Mouse:

1. Basic Module Class

Reference: src/modules/MouseUtils/FindMyMouse/dllmain.cpp:62-110

2. Settings Support

Add configuration management to your module:
Reference: src/modules/MouseUtils/FindMyMouse/dllmain.cpp:206-246

3. Hotkey Support

Add hotkey handling to your module:
Reference: src/modules/MouseUtils/FindMyMouse/dllmain.cpp:183-203

4. Multiple Hotkeys

For modules with multiple hotkeys (like Advanced Paste):
Important: The order of hotkeys returned by get_hotkeys() must match the order expected by the Settings UI for conflict detection. Reference: src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp:1053-1071

External Application Module

For modules that launch separate applications (like Color Picker):
Reference: src/modules/colorPicker/ColorPicker/dllmain.cpp:48-309

Group Policy Support

Add GPO support to allow enterprise policy control:
You’ll also need to:
  1. Add your module’s GPO function to src/common/utils/gpo.h:
  1. Define the policy registry key in src/common/utils/gpo.h:
Reference: src/modules/MouseUtils/FindMyMouse/dllmain.cpp:112-115

Telemetry

Implement telemetry to track usage:
In your module’s main thread, listen for the telemetry event and send data:
Reference: src/modules/colorPicker/ColorPicker/dllmain.cpp:161, doc/devdocs/core/settings/telemetry.md

DLL Entry Point

Every module DLL needs a DllMain function:
Reference: src/modules/MouseUtils/FindMyMouse/dllmain.cpp:38-54

Best Practices

Memory Management

  1. Clean up in disable(): Free resources, stop threads, close handles
  2. Final cleanup in destroy(): Call disable() and delete this
  3. Check enabled state: Guard operations with if (m_enabled)

Threading

  1. Don’t block enable(): Spawn threads for long-running operations
  2. Clean thread shutdown: Use events or flags to signal threads to exit
  3. Detach or join: Either detach threads or properly join them in disable()

Hotkeys

  1. Fast handlers: Hotkey handlers must execute quickly to avoid Windows deregistering the hook
  2. Spawn threads: Move actual work to background threads
  3. Return quickly: Return from on_hotkey() within milliseconds
Example:
Reference: src/modules/AdvancedPaste/AdvancedPasteModuleInterface/dllmain.cpp:990-998

Settings

  1. Validate input: Check ranges and types when parsing settings
  2. Provide defaults: Always have sensible fallback values
  3. Persist changes: Call save_to_settings_file() after user changes
  4. Apply immediately: Update running state when settings change

Logging

  1. Initialize logger: Call LoggerHelpers::init_logger() in constructor
  2. Use appropriate levels: trace, info, warn, error
  3. Include context: Log module name and operation details
  4. Don’t spam: Avoid logging in hot paths
Reference: src/modules/MouseUtils/FindMyMouse/dllmain.cpp:87-88

Testing Your Module

Manual Testing

  1. Build your module: Place DLL in modules/ folder
  2. Restart Runner: Kill PowerToys.exe and restart
  3. Check Settings UI: Your module should appear in Settings
  4. Test enable/disable: Toggle module and verify behavior
  5. Test hotkeys: Press configured hotkeys and check logs
  6. Test settings: Change settings and verify they apply

Debugging

  1. Attach debugger to PowerToys.exe process
  2. Set breakpoints in your module’s DLL code
  3. Check logs: %LOCALAPPDATA%\Microsoft\PowerToys\logs\
  4. Use debug builds: Debug symbols help tremendously

Complete Example: Simple Module

Here’s a complete minimal module that appears in Settings and logs when enabled:

Next Steps

Settings System

Learn how to create a Settings UI for your module

Runner Implementation

Understand how the Runner loads and manages modules

Architecture Overview

High-level system architecture

Common Libraries

Shared utilities you can use in your module