## Summary of the Pull Request ModuleLoader tool, a stand-alone Win32 executable for testing of PowerToy modules without needing branch builds. sample output from running the tool is below: .\ModuleLoader.exe .\powertoys.cursorwrap.dll PowerToys Module Loader v1.0 ============================= Loading module: .\powertoys.cursorwrap.dll Detected module name: cursorwrap Loading settings... Trying settings path: C:\Users\mikehall\AppData\Local\Microsoft\PowerToys\cursorwrap\settings.json Settings file loaded (315 characters) Settings loaded successfully. Loading module DLL... Module instance created successfully Module DLL loaded successfully. Module key: CursorWrap Module name: CursorWrap Applying settings to module... Settings applied. Registering module hotkeys... Module reports 1 legacy hotkey(s) Registering hotkey 0: Win+Alt+U - OK Hotkeys registered: 1 Enabling module... Module enabled. ============================= Module is now running! ============================= Module Status: - Name: CursorWrap - Key: CursorWrap - Enabled: Yes - Hotkeys: 1 registered Registered Hotkeys: Win+Alt+U Press Ctrl+C to exit. You can press the module's hotkey to toggle its functionality. Note that this doesn't integrate with Powertoys settings UI - this is purely to test Powertoys module functionality. ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments See details above. ## Validation Steps Performed ModuleLoader tested on Windows 11, Surface Laptop 7 Pro.
14 KiB
Sharing ModuleLoader and Modules
This guide explains how to share the ModuleLoader tool and PowerToy modules with others for testing purposes.
Overview
The ModuleLoader is designed to be a portable, standalone testing tool that can be shared with module developers and testers. It has minimal dependencies and can work with any compatible PowerToy module DLL.
What You Need to Share
For Testing a Module (e.g., CursorWrap)
Minimum Package (Recommended for Quick Testing)
-
ModuleLoader.exe - The standalone loader application
- Location:
x64\Debug\ModuleLoader.exeorx64\Release\ModuleLoader.exe - No additional DLLs required (uses only Windows system libraries)
- Location:
-
The Module DLL - The PowerToy module to test
- Example:
CursorWrap.dllfromx64\Debug\orx64\Release\ - Location varies by module (see module-specific locations below)
- Example:
-
settings.json - Module configuration (place in same folder as the DLL)
- NEW: Settings can be placed alongside the module DLL for portable testing
- Location: Same directory as the module DLL (e.g.,
settings.jsonnext toCursorWrap.dll) - Falls back to:
%LOCALAPPDATA%\Microsoft\PowerToys\<ModuleName>\settings.jsonif not found locally
Complete Standalone Package (For Users Without PowerToys Installed)
- ModuleLoader.exe
- Module DLL
- Sample settings.json - Pre-configured settings file
- Installation instructions - See "Standalone Package Setup" section below
Debug Builds
If you build the module in Debug configuration:
- The module will output debug messages via
OutputDebugString() - View these with DebugView or Visual Studio Output window
- Example: CursorWrap outputs detailed topology and cursor wrapping debug info
Module-Specific File Locations
CursorWrap
Files to share:
- x64\Debug\CursorWrap.dll (or Release)
- %LOCALAPPDATA%\Microsoft\PowerToys\CursorWrap\settings.json
Size: ~100KB
MouseHighlighter
Files to share:
- x64\Debug\MouseHighlighter.dll (or Release)
- %LOCALAPPDATA%\Microsoft\PowerToys\MouseHighlighter\settings.json
Size: ~150KB
FindMyMouse
Files to share:
- x64\Debug\FindMyMouse.dll (or Release)
- %LOCALAPPDATA%\Microsoft\PowerToys\FindMyMouse\settings.json
Size: ~120KB
MousePointerCrosshairs
Files to share:
- x64\Debug\MousePointerCrosshairs.dll (or Release)
- %LOCALAPPDATA%\Microsoft\PowerToys\MousePointerCrosshairs\settings.json
Size: ~140KB
MouseJump
Files to share:
- x64\Debug\MouseJump.dll (or Release)
- %LOCALAPPDATA%\Microsoft\PowerToys\MouseJump\settings.json
Note: MouseJump is a UI-based module and may not work fully with ModuleLoader
Size: ~200KB
AlwaysOnTop
Files to share:
- x64\Debug\AlwaysOnTop.dll (or Release)
- %LOCALAPPDATA%\Microsoft\PowerToys\AlwaysOnTop\settings.json
Size: ~100KB
Dependency Analysis
ModuleLoader.exe Dependencies
Windows System Libraries Only (automatically available on all Windows systems):
KERNEL32.dll- Core Windows APIUSER32.dll- User interface functionsSHELL32.dll- Shell functionsole32.dll- COM library
No PowerToys dependencies required! The ModuleLoader is completely standalone.
Module DLL Dependencies (Typical)
Most PowerToy modules depend on:
- Windows system DLLs (automatically available)
- PowerToys common libraries (if any, they're typically statically linked)
- Module settings - Must be present in
%LOCALAPPDATA%\Microsoft\PowerToys\<ModuleName>\
Important: Modules are generally self-contained and statically link most dependencies. You typically only need the module DLL itself.
Creating a Standalone Package
Step 1: Prepare the Files
Create a folder structure like this:
ModuleLoaderPackage\
??? ModuleLoader.exe
??? CursorWrap.dll (or other module)
??? settings.json (module settings - placed locally!)
NEW Simplified Structure: You can now place settings.json directly alongside the module DLL! The ModuleLoader will check this location first before looking in the standard PowerToys settings directories.
Step 2: Extract Settings from Your Machine
# Copy settings from your development machine
$moduleName = "CursorWrap" # Change as needed
$settingsPath = "$env:LOCALAPPDATA\Microsoft\PowerToys\$moduleName\settings.json"
Copy-Item $settingsPath ".\settings\$moduleName\settings.json"
Step 3: Create Installation Instructions (README.txt)
PowerToys Module Testing Package
=================================
This package contains the ModuleLoader tool for testing PowerToy modules.
Contents:
- ModuleLoader.exe : Standalone module loader
- modules\*.dll : PowerToy module(s) to test
- settings\*\*.json : Module configuration files
Setup (First Time):
-------------------
1. Create settings directory:
%LOCALAPPDATA%\Microsoft\PowerToys\
2. Copy settings:
Copy the entire "settings\<ModuleName>" folder to:
%LOCALAPPDATA%\Microsoft\PowerToys\
Example for CursorWrap:
Copy "settings\CursorWrap" to:
%LOCALAPPDATA%\Microsoft\PowerToys\CursorWrap\
Usage:
------
ModuleLoader.exe modules\CursorWrap.dll
The tool will:
- Load the module DLL
- Read settings from %LOCALAPPDATA%\Microsoft\PowerToys\<ModuleName>\
- Register hotkeys
- Enable the module
Press Ctrl+C to exit.
Press the module's hotkey to toggle functionality.
Requirements:
-------------
- Windows 10 1803 or later
- No PowerToys installation required!
Troubleshooting:
----------------
If you see "Settings file not found":
1. Make sure you copied the settings folder correctly
2. Check that the path is:
%LOCALAPPDATA%\Microsoft\PowerToys\<ModuleName>\settings.json
3. You can also run PowerToys once to generate default settings
Debug Logs:
-----------
Module logs are written to:
%LOCALAPPDATA%\Microsoft\PowerToys\<ModuleName>\Logs\
For debug builds, use DebugView to see real-time output.
Quick Distribution Methods
Method 1: ZIP Archive
# Create a complete package
$moduleName = "CursorWrap"
$packageName = "ModuleLoader-$moduleName-Package"
# Collect files
New-Item $packageName -ItemType Directory
Copy-Item "x64\Debug\ModuleLoader.exe" "$packageName\"
New-Item "$packageName\modules" -ItemType Directory
Copy-Item "x64\Debug\$moduleName.dll" "$packageName\modules\"
New-Item "$packageName\settings\$moduleName" -ItemType Directory -Force
Copy-Item "$env:LOCALAPPDATA\Microsoft\PowerToys\$moduleName\settings.json" "$packageName\settings\$moduleName\"
# Create README
@"
See README in the tools\module_loader folder for instructions
"@ | Out-File "$packageName\README.txt"
# Zip it
Compress-Archive -Path $packageName -DestinationPath "$packageName.zip"
Method 2: Direct Share (Advanced Users)
For developers who already have PowerToys installed:
# Just share the executables
Copy-Item "x64\Debug\ModuleLoader.exe" "\\ShareLocation\"
Copy-Item "x64\Debug\CursorWrap.dll" "\\ShareLocation\"
They can run: ModuleLoader.exe CursorWrap.dll
(Settings will be loaded from their existing PowerToys installation)
Platform-Specific Notes
x64 vs ARM64
Important: Match architectures!
x64\Debug\ModuleLoader.exe? Only works withx64module DLLsARM64\Debug\ModuleLoader.exe? Only works withARM64module DLLs
Distribution Tip: Provide both architectures if targeting multiple platforms:
ModuleLoaderPackage\
??? x64\
? ??? ModuleLoader.exe
? ??? modules\CursorWrap.dll
??? ARM64\
? ??? ModuleLoader.exe
? ??? modules\CursorWrap.dll
??? settings\...
Debug vs Release
Debug builds:
- Larger file size
- Include debug symbols
- Verbose logging via
OutputDebugString() - Recommended for testing/development
Release builds:
- Smaller file size
- Optimized performance
- Minimal logging
- Recommended for end-user testing
Testing Checklist
Before sharing a module package:
- ModuleLoader.exe is included
- Module DLL is included (matching architecture)
- Sample settings.json is included
- README/instructions are included
- Tested on a clean machine (no PowerToys installed)
- Verified hotkeys work
- Verified Ctrl+C exits cleanly
- Confirmed settings path in documentation
Advanced: Portable Package Script
Here's a complete PowerShell script to create a fully portable package:
param(
[Parameter(Mandatory=$true)]
[string]$ModuleName,
[ValidateSet("Debug", "Release")]
[string]$Configuration = "Debug",
[ValidateSet("x64", "ARM64")]
[string]$Platform = "x64"
)
$packageName = "ModuleLoader-$ModuleName-$Platform-$Configuration"
$packagePath = ".\$packageName"
Write-Host "Creating portable package: $packageName" -ForegroundColor Green
# Create structure
New-Item $packagePath -ItemType Directory -Force | Out-Null
New-Item "$packagePath\modules" -ItemType Directory -Force | Out-Null
New-Item "$packagePath\settings\$ModuleName" -ItemType Directory -Force | Out-Null
# Copy ModuleLoader
$loaderPath = "$Platform\$Configuration\ModuleLoader.exe"
if (Test-Path $loaderPath) {
Copy-Item $loaderPath "$packagePath\"
Write-Host "? Copied ModuleLoader.exe" -ForegroundColor Green
} else {
Write-Host "? ModuleLoader.exe not found at $loaderPath" -ForegroundColor Red
exit 1
}
# Copy Module DLL
$modulePath = "$Platform\$Configuration\$ModuleName.dll"
if (Test-Path $modulePath) {
Copy-Item $modulePath "$packagePath\modules\"
Write-Host "? Copied $ModuleName.dll" -ForegroundColor Green
} else {
Write-Host "? $ModuleName.dll not found at $modulePath" -ForegroundColor Red
exit 1
}
# Copy Settings
$settingsPath = "$env:LOCALAPPDATA\Microsoft\PowerToys\$ModuleName\settings.json"
if (Test-Path $settingsPath) {
Copy-Item $settingsPath "$packagePath\settings\$ModuleName\"
Write-Host "? Copied settings.json" -ForegroundColor Green
} else {
Write-Host "? Settings not found at $settingsPath - creating placeholder" -ForegroundColor Yellow
@"
{
"name": "$ModuleName",
"version": "1.0"
}
"@ | Out-File "$packagePath\settings\$ModuleName\settings.json"
}
# Create README
@"
PowerToys $ModuleName Testing Package
======================================
Configuration: $Configuration
Platform: $Platform
Setup Instructions:
-------------------
1. Copy the 'settings\$ModuleName' folder to:
%LOCALAPPDATA%\Microsoft\PowerToys\
2. Run:
ModuleLoader.exe modules\$ModuleName.dll
3. Press Ctrl+C to exit
Logs are written to:
%LOCALAPPDATA%\Microsoft\PowerToys\$ModuleName\Logs\
For more information, see:
https://github.com/microsoft/PowerToys/tree/main/tools/module_loader
"@ | Out-File "$packagePath\README.txt"
# Create ZIP
$zipPath = "$packageName.zip"
Compress-Archive -Path $packagePath -DestinationPath $zipPath -Force
Write-Host "? Created $zipPath" -ForegroundColor Green
# Show summary
Write-Host "`nPackage Contents:" -ForegroundColor Cyan
Get-ChildItem $packagePath -Recurse | ForEach-Object {
Write-Host " $($_.FullName.Replace($packagePath, ''))"
}
Write-Host "`nPackage ready: $zipPath" -ForegroundColor Green
Write-Host "Size: $([math]::Round((Get-Item $zipPath).Length / 1KB, 2)) KB"
Usage:
.\CreateModulePackage.ps1 -ModuleName "CursorWrap" -Configuration Release -Platform x64
FAQ
Q: Can I share just ModuleLoader.exe and the module DLL?
A: Yes, but the recipient must have PowerToys installed (or manually create the settings file).
Q: Does the tester need PowerToys installed?
A: No, if you provide the complete package with settings. ModuleLoader is fully standalone.
Q: What if settings.json doesn't exist?
A: ModuleLoader will show an error. Either:
- Run PowerToys once with the module enabled to generate settings
- Manually create a minimal settings.json file
- Include a sample settings.json in your package
Q: Can I test modules on a virtual machine?
A: Yes! This is a great use case. Just copy the package to the VM - no PowerToys installation needed.
Q: Do I need to include PDB files?
A: Only for debugging. For normal testing, just the EXE and DLL are sufficient.
Q: Can I distribute this to end users?
A: ModuleLoader is a development/testing tool, not intended for end-user distribution. For production use, direct users to install PowerToys.
Security Considerations
When sharing module DLLs:
- Verify Source: Only share modules you built from trusted source code
- Scan for Malware: Run antivirus scans on the package before sharing
- HTTPS Only: Use secure channels (HTTPS, OneDrive, SharePoint) for distribution
- Hash Verification: Consider providing SHA256 hashes for file integrity:
Get-FileHash ModuleLoader.exe -Algorithm SHA256 Get-FileHash modules\CursorWrap.dll -Algorithm SHA256
Example Package (CursorWrap)
Here's what a complete CursorWrap testing package looks like:
ModuleLoader-CursorWrap-x64-Debug.zip (220 KB)
?
??? ModuleLoader-CursorWrap-x64-Debug\
??? ModuleLoader.exe (160 KB)
??? README.txt (2 KB)
??? modules\
? ??? CursorWrap.dll (55 KB)
??? settings\
??? CursorWrap\
??? settings.json (3 KB)
Total package size: ~220 KB (compressed)
Support
For issues with ModuleLoader, see:
License
ModuleLoader is part of PowerToys and is licensed under the MIT License. See the LICENSE file in the PowerToys repository root for details.