This guide covers the complete process of creating a new PowerToys utility. Follow each section in order for best results.
Overview
A PowerToys module is a self-contained utility integrated into the PowerToys ecosystem. Modules can be:- UI-only: Standalone applications launched on-demand (e.g., ColorPicker)
- Background service: Always-running services (e.g., Awake, LightSwitch)
- Hybrid: Combination of UI and background logic (e.g., ShortcutGuide, FancyZones)
- C++/C# interop: Mixed native and managed code (e.g., PowerRename)
Prerequisites
Before starting:- ✅ Complete the Getting Started guide
- ✅ Successfully build and run
PowerToys.slnx - ✅ Understand debugging techniques
- ✅ Familiarize yourself with coding style
- WiX v5 toolset (for building installer)
- Multiple monitors (for testing multi-display utilities)
Planning Your Module
1. Design Decisions
Answer these questions before coding:| Question | Consider |
|---|---|
| What does the module do? | Clear, focused functionality |
| How does it start? | On-demand, at startup, event-triggered? |
| Does it need UI? | Settings only, main UI, both? |
| What’s the lifecycle? | Always running, launched temporarily? |
| What language? | C++ (performance), C# (ease), or both? |
| Similar modules? | Study existing modules with similar patterns |
2. Study Similar Modules
UI-only modules:ColorPicker- Simple activation and UIPowerOCR- On-demand text recognitionMeasureTool- Overlay-based measurement
Awake- Keep-alive serviceLightSwitch- System theme monitorAlwaysOnTop- Window state management
FancyZones- Service + editor UIShortcutGuide- Background + overlayWorkspaces- Complex UI + window management
PowerRename- Explorer extension + UIFileLocksmith- Shell integration + UIImageResizer- Context menu + processing
Module Architecture
Folder Structure
Create your module undersrc/modules/:
Step 1: Create Module Interface
The Module Interface is required - it’s how PowerToys Runner communicates with your module.Using the Project Template
-
Use the module template:
-
Copy generated files to
src\modules\YourModule\YourModuleModuleInterface\ - Update all GUIDs in project files
- Update namespaces and class names
Module Interface Structure
Key components indllmain.cpp:
1. Settings Structure
2. Module Class
3. Required Methods
Module Identification:Export Module
At the end ofdllmain.cpp:
Step 2: Register Module with Runner
Your module must be registered in multiple locations:1. src/runner/modules.h
Add to the module list:
2. src/runner/modules.cpp
Add module loading:
3. src/common/logger/logger.h
Add logging category:
4. src/runner/settings_window.h and .cpp
Add to settings enumeration and mapping.
Step 3: Build Module Service/UI
This is the main functionality of your module.C++ Service Example
C# WinUI App Example
Create WinUI 3 Blank App project:Project Configuration
Set the output path in your.vcxproj or .csproj:
Step 4: Settings Integration
Integrate your module with PowerToys Settings UI.1. Create Settings Classes
src/settings-ui/Settings.UI.Library/YourModuleProperties.cs:
src/settings-ui/Settings.UI.Library/YourModuleSettings.cs:
2. Create ViewModel
src/settings-ui/Settings.UI/ViewModels/YourModuleViewModel.cs:
3. Create Settings Page
src/settings-ui/Settings.UI/SettingsXAML/Views/YourModulePage.xaml:
4. Add Resource Strings
src/settings-ui/Settings.UI/Strings/en-us/Resources.resw:
Step 5: OOBE Page
Create Out-of-Box Experience page for new users.src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeYourModule.xaml:
src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs:
Step 6: Installer Integration
Add your module to the WiX installer.1. Create WiX Component File
installer/PowerToysInstallerVNext/YourModule.wxs:
2. Update Product.wxs
installer/PowerToysInstallerVNext/Product.wxs:
Add to <Feature Id="CoreFeature">:
3. Update File Generation Script
installer/PowerToysInstallerVNext/generateFileComponents.ps1:
Add at the end:
Step 7: Build and Test
Build Your Module
Debug Your Module
- Set
runneras startup project - Start debugging (
F5) - Enable your module in Settings
- Attach to your module’s process:
- Press
Ctrl+Alt+P - Search for
PowerToys.YourModule.exe - Attach debugger
- Press
Test Scenarios
- Module appears in Settings UI
- Enable/disable works correctly
- Settings persist after restart
- Hotkey activation works (if applicable)
- Module starts with PowerToys
- Module logs correctly
- No crashes or memory leaks
- Works in elevated and non-elevated modes
- OOBE page displays correctly
Step 8: Testing
Write comprehensive tests for your module.Unit Tests
Create test project:src/modules/YourModule/Tests/YourModule-UnitTests/
See Testing Guide for details.
UI Tests
Create UI test project:src/modules/YourModule/Tests/YourModule-UITests/
See Testing Guide for details.
Fuzz Tests (if applicable)
If your module handles file I/O or user input, implement fuzz tests. See Testing Guide for details.Step 9: Documentation
Developer Documentation
Createdoc/devdocs/modules/your-module.md:
User Documentation
The PowerToys team will create Microsoft Learn documentation for users.Common Pitfalls
Module Not Loading
Symptoms: Module doesn’t appear in Settings Check:- Module registered in
modules.handmodules.cpp - DLL path correct in
module_dllsarray - Module key matches everywhere
- Module interface exports
powertoy_create()correctly
Settings Not Persisting
Symptoms: Settings reset after restart Check:- Settings saved to correct path:
%LOCALAPPDATA%\Microsoft\PowerToys\YourModule\settings.json - JSON serialization correct
- Settings loaded in
init_settings() - File watcher implemented for settings changes
Module Crashes Runner
Symptoms: PowerToys crashes when module loads Check:- No exceptions in module constructor
- Proper error handling in interface methods
- Resources cleaned up in destructor
- No memory leaks
- Logs show error details
Hotkey Not Working
Symptoms: Hotkey doesn’t activate module Check:- Hotkey parsed correctly in settings
-
get_hotkeys()returns correct hotkey -
on_hotkey()handles activation - Module is enabled
- No conflicting hotkeys
Checklist
Before submitting your module:Code Complete
- Module interface implemented
- Service/UI implemented
- Settings integration complete
- OOBE page created
- Installer integration done
- Tests written and passing
- Documentation created
Quality
- Code follows style guidelines
- No hardcoded strings (use resources)
- Proper error handling
- Logging implemented
- No memory leaks
- Thread-safe where needed
Testing
- Builds successfully
- Unit tests pass
- UI tests pass (if applicable)
- Fuzz tests implemented (if handling file I/O)
- Tested in Debug and Release
- Tested elevated and non-elevated
- Tested on multiple monitors (if applicable)
- Tested clean install
Integration
- Registered in runner
- GPO support added
- Settings UI complete
- OOBE page works
- Installer includes module
- Telemetry events defined
Next Steps
Building
Build your module and PowerToys
Debugging
Debug your module effectively
Testing
Write comprehensive tests
Contributing
Submit your module via pull request
Getting Help
If you need assistance:- Check existing modules for examples
- Review developer documentation
- Open an issue with tag
Needs-Team-Response - Join discussions in the PowerToys repository