Files
PowerToys/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/dllmain.cpp

379 lines
12 KiB
C++
Raw Normal View History

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <mutex>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/winapi_error.h>
#include <common/utils/logger_helper.h>
#include <common/interop/shared_constants.h>
#include "../interface/powertoy_module_interface.h"
#include "Generated Files/resource.h"
#include <common/SettingsAPI/settings_objects.h>
[Settings][runner]Quick access system tray launcher (#22408) * Init * Fix running settings * UI design * Left click trigger Wire up colorpicker and pt run * Wire up others * Update FlyoutWindow.xaml.cs * Removed comments * Update FlyoutWindow.xaml * More work * Open Settings page * More UI work * Resolve conflicts * [General] SystemTray Flyout: Add update on tray items' visibility when module gets enabled/disabled Also remove context menu opening on tray icon. * Adding app list * Adding more buttons, resolving conflicts * [General] Flyout: improving opening, closing flyout/settings window. Implementing basic bahaviour on enabling/disabling modules. * [General] FlyoutWindow: proceed with implementation. GPO works. Main functionallity works (launching and enabling apps). * [general] flyout: fix exit button * [general] flyout: implement double click handling * Localization * [Generel] Flyout: Re-implement flyout launching, add workaround: disable flyout hiding in case the user switches on modules on the all apps page + minor changes * [general] flyout: restore the context menu when right clicking on system tray icon * Fix spellchecker * [installer] fixing missing dll files + suppress error on not signed script * Fix spell checker * Fix flyout not focusing when activated * Refresh Settings UI enabled state when flyout changes * fix spellcheck * Remove VCM from the list * [General] flyout: fix settings window opening. Switch to general page only if there is no page opened * [general] flyout: add launching hosts app * Fix CI build * adding check on elevation when launching hosts * Use localization strings that already exist * Remove dll not present in arm64 build * Adding GPO policy check for the launcher page items * fix hosts launching * Add telemetry * Also hide from all apps list when gpo is force enabling * fix spellchecker * Improve focus issues * Fix flickering Bitmap Icons * Fix telemetry error * Fix telemetry call * Fix wrong comment --------- Co-authored-by: Stefan Markovic <stefan@janeasystems.com> Co-authored-by: Laszlo Nemeth <laszlo.nemeth.hu@gmail.com> Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2023-01-31 00:00:11 +01:00
#include <common/utils/EventWaiter.h>
BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD /*ul_reason_for_call*/, LPVOID /*lpReserved*/)
{
return TRUE;
}
class ShortcutGuideModule : public PowertoyModuleIface
{
public:
ShortcutGuideModule()
{
app_name = GET_RESOURCE_STRING(IDS_SHORTCUT_GUIDE);
app_key = L"Shortcut Guide";
LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::shortcutGuideLoggerName);
std::filesystem::path oldLogPath(PTSettingsHelper::get_module_save_folder_location(app_key));
oldLogPath.append("ShortcutGuideLogs");
LoggerHelpers::delete_old_log_folder(oldLogPath);
exitEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::SHORTCUT_GUIDE_EXIT_EVENT);
if (!exitEvent)
{
Logger::warn(L"Failed to create {} event. {}", CommonSharedConstants::SHORTCUT_GUIDE_EXIT_EVENT, get_last_error_or_default(GetLastError()));
}
[Settings][runner]Quick access system tray launcher (#22408) * Init * Fix running settings * UI design * Left click trigger Wire up colorpicker and pt run * Wire up others * Update FlyoutWindow.xaml.cs * Removed comments * Update FlyoutWindow.xaml * More work * Open Settings page * More UI work * Resolve conflicts * [General] SystemTray Flyout: Add update on tray items' visibility when module gets enabled/disabled Also remove context menu opening on tray icon. * Adding app list * Adding more buttons, resolving conflicts * [General] Flyout: improving opening, closing flyout/settings window. Implementing basic bahaviour on enabling/disabling modules. * [General] FlyoutWindow: proceed with implementation. GPO works. Main functionallity works (launching and enabling apps). * [general] flyout: fix exit button * [general] flyout: implement double click handling * Localization * [Generel] Flyout: Re-implement flyout launching, add workaround: disable flyout hiding in case the user switches on modules on the all apps page + minor changes * [general] flyout: restore the context menu when right clicking on system tray icon * Fix spellchecker * [installer] fixing missing dll files + suppress error on not signed script * Fix spell checker * Fix flyout not focusing when activated * Refresh Settings UI enabled state when flyout changes * fix spellcheck * Remove VCM from the list * [General] flyout: fix settings window opening. Switch to general page only if there is no page opened * [general] flyout: add launching hosts app * Fix CI build * adding check on elevation when launching hosts * Use localization strings that already exist * Remove dll not present in arm64 build * Adding GPO policy check for the launcher page items * fix hosts launching * Add telemetry * Also hide from all apps list when gpo is force enabling * fix spellchecker * Improve focus issues * Fix flickering Bitmap Icons * Fix telemetry error * Fix telemetry call * Fix wrong comment --------- Co-authored-by: Stefan Markovic <stefan@janeasystems.com> Co-authored-by: Laszlo Nemeth <laszlo.nemeth.hu@gmail.com> Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2023-01-31 00:00:11 +01:00
triggerEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::SHORTCUT_GUIDE_TRIGGER_EVENT);
triggerEventWaiter = EventWaiter(CommonSharedConstants::SHORTCUT_GUIDE_TRIGGER_EVENT, [this](int) {
OnHotkeyEx();
});
InitSettings();
}
virtual const wchar_t* get_name() override
{
return app_name.c_str();
}
virtual const wchar_t* get_key() override
{
return app_key.c_str();
}
2022-10-26 14:02:31 +01:00
// Return the configured status for the gpo policy for the module
virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
{
return powertoys_gpo::getConfiguredShortcutGuideEnabledValue();
}
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
PowerToysSettings::Settings settings(hinstance, get_name());
return settings.serialize_to_buffer(buffer, buffer_size);
}
virtual void set_config(const wchar_t* config) override
{
Logger::trace("set_config()");
try
{
// Parse the input JSON string.
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
ParseSettings(values);
}
catch (std::exception& ex)
{
Logger::error("Failed to parse settings. {}", ex.what());
}
}
virtual void enable() override
{
Logger::info("Shortcut Guide is enabling");
if (!_enabled)
{
_enabled = true;
}
else
{
Logger::warn("Shortcut guide is already enabled");
}
}
virtual void disable() override
{
Logger::info("ShortcutGuideModule::disable()");
if (_enabled)
{
_enabled = false;
TerminateProcess();
}
else
{
Logger::warn("Shortcut Guide is already disabled");
}
}
virtual bool is_enabled() override
{
return _enabled;
}
virtual void destroy() override
{
this->disable();
if (exitEvent)
{
CloseHandle(exitEvent);
}
delete this;
}
virtual std::optional<HotkeyEx> GetHotkeyEx() override
{
Logger::trace("GetHotkeyEx()");
if (m_shouldReactToPressedWinKey)
{
return std::nullopt;
}
return m_hotkey;
}
virtual void OnHotkeyEx() override
{
Logger::trace("OnHotkeyEx()");
if (!_enabled)
{
return;
}
if (IsProcessActive())
{
TerminateProcess();
return;
}
if (m_hProcess)
{
CloseHandle(m_hProcess);
m_hProcess = nullptr;
}
StartProcess();
}
virtual void send_settings_telemetry() override
{
Logger::trace("Send settings telemetry");
if (!StartProcess(L"telemetry"))
{
Logger::error("Failed to create a process to send settings telemetry");
}
}
virtual bool keep_track_of_pressed_win_key() override
{
return m_shouldReactToPressedWinKey;
}
virtual UINT milliseconds_win_key_must_be_pressed() override
{
return std::min(m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts, m_millisecondsWinKeyPressTimeForTaskbarIconShortcuts);
}
private:
std::wstring app_name;
//contains the non localized key of the powertoy
std::wstring app_key;
bool _enabled = false;
HANDLE m_hProcess = nullptr;
// Hotkey to invoke the module
HotkeyEx m_hotkey;
// If the module should be activated through the legacy pressing windows key behavior.
const UINT DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_GLOBAL_WINDOWS_SHORTCUTS = 900;
const UINT DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_TASKBAR_ICON_SHORTCUTS = 900;
bool m_shouldReactToPressedWinKey = false;
UINT m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts = DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_GLOBAL_WINDOWS_SHORTCUTS;
UINT m_millisecondsWinKeyPressTimeForTaskbarIconShortcuts = DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_TASKBAR_ICON_SHORTCUTS;
[Settings][runner]Quick access system tray launcher (#22408) * Init * Fix running settings * UI design * Left click trigger Wire up colorpicker and pt run * Wire up others * Update FlyoutWindow.xaml.cs * Removed comments * Update FlyoutWindow.xaml * More work * Open Settings page * More UI work * Resolve conflicts * [General] SystemTray Flyout: Add update on tray items' visibility when module gets enabled/disabled Also remove context menu opening on tray icon. * Adding app list * Adding more buttons, resolving conflicts * [General] Flyout: improving opening, closing flyout/settings window. Implementing basic bahaviour on enabling/disabling modules. * [General] FlyoutWindow: proceed with implementation. GPO works. Main functionallity works (launching and enabling apps). * [general] flyout: fix exit button * [general] flyout: implement double click handling * Localization * [Generel] Flyout: Re-implement flyout launching, add workaround: disable flyout hiding in case the user switches on modules on the all apps page + minor changes * [general] flyout: restore the context menu when right clicking on system tray icon * Fix spellchecker * [installer] fixing missing dll files + suppress error on not signed script * Fix spell checker * Fix flyout not focusing when activated * Refresh Settings UI enabled state when flyout changes * fix spellcheck * Remove VCM from the list * [General] flyout: fix settings window opening. Switch to general page only if there is no page opened * [general] flyout: add launching hosts app * Fix CI build * adding check on elevation when launching hosts * Use localization strings that already exist * Remove dll not present in arm64 build * Adding GPO policy check for the launcher page items * fix hosts launching * Add telemetry * Also hide from all apps list when gpo is force enabling * fix spellchecker * Improve focus issues * Fix flickering Bitmap Icons * Fix telemetry error * Fix telemetry call * Fix wrong comment --------- Co-authored-by: Stefan Markovic <stefan@janeasystems.com> Co-authored-by: Laszlo Nemeth <laszlo.nemeth.hu@gmail.com> Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2023-01-31 00:00:11 +01:00
HANDLE triggerEvent;
HANDLE exitEvent;
[Settings][runner]Quick access system tray launcher (#22408) * Init * Fix running settings * UI design * Left click trigger Wire up colorpicker and pt run * Wire up others * Update FlyoutWindow.xaml.cs * Removed comments * Update FlyoutWindow.xaml * More work * Open Settings page * More UI work * Resolve conflicts * [General] SystemTray Flyout: Add update on tray items' visibility when module gets enabled/disabled Also remove context menu opening on tray icon. * Adding app list * Adding more buttons, resolving conflicts * [General] Flyout: improving opening, closing flyout/settings window. Implementing basic bahaviour on enabling/disabling modules. * [General] FlyoutWindow: proceed with implementation. GPO works. Main functionallity works (launching and enabling apps). * [general] flyout: fix exit button * [general] flyout: implement double click handling * Localization * [Generel] Flyout: Re-implement flyout launching, add workaround: disable flyout hiding in case the user switches on modules on the all apps page + minor changes * [general] flyout: restore the context menu when right clicking on system tray icon * Fix spellchecker * [installer] fixing missing dll files + suppress error on not signed script * Fix spell checker * Fix flyout not focusing when activated * Refresh Settings UI enabled state when flyout changes * fix spellcheck * Remove VCM from the list * [General] flyout: fix settings window opening. Switch to general page only if there is no page opened * [general] flyout: add launching hosts app * Fix CI build * adding check on elevation when launching hosts * Use localization strings that already exist * Remove dll not present in arm64 build * Adding GPO policy check for the launcher page items * fix hosts launching * Add telemetry * Also hide from all apps list when gpo is force enabling * fix spellchecker * Improve focus issues * Fix flickering Bitmap Icons * Fix telemetry error * Fix telemetry call * Fix wrong comment --------- Co-authored-by: Stefan Markovic <stefan@janeasystems.com> Co-authored-by: Laszlo Nemeth <laszlo.nemeth.hu@gmail.com> Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2023-01-31 00:00:11 +01:00
EventWaiter triggerEventWaiter;
bool StartProcess(std::wstring args = L"")
{
if (exitEvent)
{
ResetEvent(exitEvent);
}
unsigned long powertoys_pid = GetCurrentProcessId();
std::wstring executable_args = L"";
executable_args.append(std::to_wstring(powertoys_pid));
if (!args.empty())
{
executable_args.append(L" ");
executable_args.append(args);
}
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
[General]Reduce installer size by flattening application paths (#27451) * Flatten everything and succeed build * Figure out Settings assets * Remove UseCommonOutputDirectory tag * Proper settings app path * [VCM] Fix assets location * Fix some runtime paths * [RegistryPreview]Use MRTCore specific pri file * [Hosts]Use MRTCore specific pri file * [Settings]Use MRTCore specific pri file * [Peek]Use MRTCore specific pri file * [FileLocksmith]Use MRTCore specific pri file * [ScreenRuler]Use MRTCore specific pri file * [PowerRename]Use MRTCore specific pri file * [Peek]Move assets to own folder * [FileLocksmith] Use own Assets path * [Hosts]Use own assets folder * [PowerRename]Use own assets dir * [MeasureTool] Use its own assets folder * [ImageResizer]Use its own assets path * Fix spellcheck * Fix tab instead of space in project files * Normalize target frameworks and platforms * Remove WINRT_NO_MAKE_DETECTION flag. No longer needed? * Fix AOT and Hosts locations * Fix Dll version differences on dependency * Add Common.UI.csproj as refernce to fix dll versions * Update ControlzEx to normalize dll versions * Update System.Management version to 7.0.2 * Add GPOWrapper to Registry Preview to fix dll versions * [PTRun]Reference Microsoft.Extensions.Hosting to fix dll versions * Fix remaining output paths / dll version conflicts * [KeyboardManager]Executables still on their own directories * Fix Monaco paths * WinAppSDK apps get to play outside again * Enable VCM settings again * Fix KBM Editor path again * [Monaco]Set to own Assets dir * Fix installer preamble; Fix publish. remove unneeded publishes * Remove Hardlink functions * Installer builds again (still needs work to work) * Readd Monaco to spellcheck excludes * Fix spellcheck and call publish.cmd again * [Installer] Remove components that don't need own dirs * [Installer] Refactor Power Launcher * [Installer] Refactor Color Picker * [Installer] Refactor Monaco assets * [Installer]Generate File script no longer needs to remove files * [Installer]Refactor FileLocksmith * [Installer] Refactor Hosts * [Installer]Refactor Image Resizer * [Installer]Refactor MouseUtils * [Installer]Refactor MWB * [Installer]Refactor MeasureTool * [Installer]Refactor Peek * [Installer]Refactor PowerRename and registry fixes * [Installer]Refactor RegistryPreview * [Installer]Refactor ShortcutGuide * [Installer]Refactor Settings * [Installer]Clean up some unused stuff * [Installer]Clean up stuff for user install * [Installer]Fix WinUi3Apps wxs * [Installer]Fix misplaced folders * [Installer]Move x86 VCM dll to right path * Fix monaco language list location * [Installer]Fix VCM directory reference * [CI]Fix signing * [Installer] Fix resources folder for release CI * [ci]Looks like we still ship NLog on PowerToys Run * [Settings]Add dependency to avoid dll collision with Experimentation * [RegistryPreview]Move XAML files to own path * [RegistryPreview]Fix app icon * [Hosts]Move XAML files to their own path * [FileLocksmith]Move XAML files to their own path * [Peek]Move XAML files to own path * [ScreenRuler]Move XAML files to its own path * [Settings]Move XAML to its own path * [ColorPicker]Move Resources to Assets * [ShortcutGuide]Move svgs to own Assets path * [Awake]Move images to assets path * [Runner]Remove debug checks for PowerToys Run assets * [PTRun]Move images to its own assets path * [ImageResizer]Icon for context menu on own assets path * [PowerRename]Move ico to its own path * Remove unneeded intermediary directories * Remove further int dirs * Move tests to its own output path * Fix spellcheck * spellcheck: remove warnings * [CppAnalyzers]Ignore rule in a tool * [CI]Check if all deps.json files reference same versions * fix spellcheck * [ci]Fix task identation * [ci]Add script to guard against asset conflicts * [ci]Add more deps.json audit steps in the release build * Add xbf to spellcheck expects * Fix typo in asset conflict check scripts * Fix some more dependency conflicts * Downgrade CsWinRT to have the same dll version as sdk * [ci]Do a recursive check for every deps.json * Fix spellcheck error inside comment * [ci]Fix asset script error * [ci]Name deps.json verify tasks a bit better * [ci]Improve deps json verify script output * [ci]Update WinRT version to the same running in CI * Also upgrade CsWinRT in NOTICE.MD * [PowerRename]Move XAML files to own path * [Common]Fix Settings executable path * [ci]Verify there's no xbf files in app directories * [installer]Fix firewall path * [Monaco]Move new files to their proper assets path * [Monaco]Fix paths for new files after merge * [Feedback]Removed unneeded build conditions * [Feedback]Clear vcxproj direct reference to frameworks * [Feedback]RunPlugins name to hold PTRun plugins * [Feedback]Remove unneeded foreach * [Feedback]Shortcut Guide svgs with ** in project file * [Feedback]Fix spellcheck
2023-07-20 00:12:46 +01:00
sei.lpFile = L"PowerToys.ShortcutGuide.exe";
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = executable_args.data();
if (ShellExecuteExW(&sei) == false)
{
Logger::error(L"Failed to start SG process. {}", get_last_error_or_default(GetLastError()));
auto message = get_last_error_message(GetLastError());
if (message.has_value())
{
Logger::error(message.value());
}
return false;
}
Logger::trace(L"Started SG process with pid={}", GetProcessId(sei.hProcess));
m_hProcess = sei.hProcess;
return true;
}
void TerminateProcess()
{
if (m_hProcess)
{
if (WaitForSingleObject(m_hProcess, 0) != WAIT_OBJECT_0)
{
if (exitEvent && SetEvent(exitEvent))
{
Logger::trace(L"Signaled {}", CommonSharedConstants::SHORTCUT_GUIDE_EXIT_EVENT);
}
else
{
Logger::warn(L"Failed to signal {}", CommonSharedConstants::SHORTCUT_GUIDE_EXIT_EVENT);
}
}
else
{
CloseHandle(m_hProcess);
m_hProcess = nullptr;
Logger::trace("SG process was already terminated");
}
}
}
bool IsProcessActive()
{
return m_hProcess && WaitForSingleObject(m_hProcess, 0) != WAIT_OBJECT_0;
}
void InitSettings()
{
try
{
PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(app_key);
ParseSettings(settings);
}
catch (std::exception& ex)
{
Logger::error("Failed to init settings. {}", ex.what());
}
catch (...)
{
Logger::error("Failed to init settings");
}
}
void ParseSettings(PowerToysSettings::PowerToyValues& settings)
{
m_shouldReactToPressedWinKey = false;
m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts = DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_GLOBAL_WINDOWS_SHORTCUTS;
m_millisecondsWinKeyPressTimeForTaskbarIconShortcuts = DEFAULT_MILLISECONDS_WIN_KEY_PRESS_TIME_FOR_TASKBAR_ICON_SHORTCUTS;
auto settingsObject = settings.get_raw_json();
if (settingsObject.GetView().Size())
{
try
{
// Parse HotKey
auto jsonHotkeyObject = settingsObject.GetNamedObject(L"properties").GetNamedObject(L"open_shortcutguide");
auto hotkey = PowerToysSettings::HotkeyObject::from_json(jsonHotkeyObject);
m_hotkey = HotkeyEx();
if (hotkey.win_pressed())
{
m_hotkey.modifiersMask |= MOD_WIN;
}
if (hotkey.ctrl_pressed())
{
m_hotkey.modifiersMask |= MOD_CONTROL;
}
if (hotkey.shift_pressed())
{
m_hotkey.modifiersMask |= MOD_SHIFT;
}
if (hotkey.alt_pressed())
{
m_hotkey.modifiersMask |= MOD_ALT;
}
m_hotkey.vkCode = static_cast<WORD>(hotkey.get_code());
}
catch (...)
{
Logger::warn("Failed to initialize Shortcut Guide start shortcut");
}
try
{
// Parse Legacy windows key press behavior settings
auto jsonUseLegacyWinKeyBehaviorObject = settingsObject.GetNamedObject(L"properties").GetNamedObject(L"use_legacy_press_win_key_behavior");
m_shouldReactToPressedWinKey = jsonUseLegacyWinKeyBehaviorObject.GetNamedBoolean(L"value");
auto jsonPressTimeForGlobalWindowsShortcutsObject = settingsObject.GetNamedObject(L"properties").GetNamedObject(L"press_time");
auto jsonPressTimeForTaskbarIconShortcutsObject = settingsObject.GetNamedObject(L"properties").GetNamedObject(L"press_time_for_taskbar_icon_shortcuts");
int value = static_cast<int>(jsonPressTimeForGlobalWindowsShortcutsObject.GetNamedNumber(L"value"));
if (value >= 0)
{
m_millisecondsWinKeyPressTimeForGlobalWindowsShortcuts = value;
}
else
{
throw std::runtime_error("Invalid Press Time Windows Shortcuts value");
}
value = static_cast<int>(jsonPressTimeForTaskbarIconShortcutsObject.GetNamedNumber(L"value"));
if (value >= 0)
{
m_millisecondsWinKeyPressTimeForTaskbarIconShortcuts = value;
}
else
{
throw std::runtime_error("Invalid Press Time Taskbar Shortcuts value");
}
}
catch (...)
{
Logger::warn("Failed to get legacy win key behavior settings");
}
}
else
{
Logger::info("Shortcut Guide settings are empty");
}
if (!m_hotkey.modifiersMask)
{
Logger::info("Shortcut Guide is going to use default shortcut");
m_hotkey.modifiersMask = MOD_SHIFT | MOD_WIN;
m_hotkey.vkCode = VK_OEM_2;
}
}
};
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new ShortcutGuideModule();
}