Files
PowerToys/tools/module_loader/src/ModuleLoader.h
Mike Hall 452e0dcf51 Module Loader tool for rapid testing of modules (#43813)
## 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.
2025-11-26 22:08:34 +08:00

103 lines
2.8 KiB
C++

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#pragma once
#include <Windows.h>
#include <string>
#include <vector>
#include <powertoy_module_interface.h>
/// <summary>
/// Wrapper class for loading and managing a PowerToy module DLL
/// </summary>
class ModuleLoader
{
public:
ModuleLoader();
~ModuleLoader();
// Prevent copying
ModuleLoader(const ModuleLoader&) = delete;
ModuleLoader& operator=(const ModuleLoader&) = delete;
/// <summary>
/// Load a PowerToy module DLL
/// </summary>
/// <param name="dllPath">Path to the module DLL</param>
/// <returns>True if successful, false otherwise</returns>
bool Load(const std::wstring& dllPath);
/// <summary>
/// Enable the loaded module
/// </summary>
void Enable();
/// <summary>
/// Disable the loaded module
/// </summary>
void Disable();
/// <summary>
/// Check if the module is enabled
/// </summary>
/// <returns>True if enabled, false otherwise</returns>
bool IsEnabled() const;
/// <summary>
/// Set configuration for the module
/// </summary>
/// <param name="configJson">JSON configuration string</param>
void SetConfig(const std::wstring& configJson);
/// <summary>
/// Get the module's localized name
/// </summary>
/// <returns>Module name</returns>
std::wstring GetModuleName() const;
/// <summary>
/// Get the module's non-localized key
/// </summary>
/// <returns>Module key</returns>
std::wstring GetModuleKey() const;
/// <summary>
/// Get the module's hotkeys
/// </summary>
/// <param name="buffer">Buffer to store hotkeys</param>
/// <param name="bufferSize">Size of the buffer</param>
/// <returns>Number of hotkeys returned</returns>
size_t GetHotkeys(PowertoyModuleIface::Hotkey* buffer, size_t bufferSize);
/// <summary>
/// Trigger a hotkey callback on the module
/// </summary>
/// <param name="hotkeyId">ID of the hotkey to trigger</param>
/// <returns>True if the key press should be swallowed</returns>
bool OnHotkey(size_t hotkeyId);
/// <summary>
/// Check if the module is loaded
/// </summary>
/// <returns>True if loaded, false otherwise</returns>
bool IsLoaded() const { return m_module != nullptr; }
/// <summary>
/// Get the module's activation hotkey (newer HotkeyEx API)
/// </summary>
/// <returns>Optional HotkeyEx struct</returns>
std::optional<PowertoyModuleIface::HotkeyEx> GetHotkeyEx();
/// <summary>
/// Trigger the newer-style hotkey callback on the module
/// </summary>
void OnHotkeyEx();
private:
HMODULE m_hModule;
PowertoyModuleIface* m_module;
std::wstring m_dllPath;
};