2019-09-04 18:26:26 +02:00
|
|
|
#include "pch.h"
|
|
|
|
|
#include <ShellScalingApi.h>
|
|
|
|
|
#include <lmcons.h>
|
|
|
|
|
#include <filesystem>
|
2021-09-29 12:54:05 +02:00
|
|
|
#include <sstream>
|
2019-09-04 18:26:26 +02:00
|
|
|
#include "tray_icon.h"
|
|
|
|
|
#include "powertoy_module.h"
|
|
|
|
|
#include "trace.h"
|
|
|
|
|
#include "general_settings.h"
|
2019-12-16 18:36:52 +01:00
|
|
|
#include "restart_elevated.h"
|
2020-12-15 15:16:09 +03:00
|
|
|
#include "RestartManagement.h"
|
2020-09-10 16:57:16 +03:00
|
|
|
#include "Generated files/resource.h"
|
2021-03-19 19:03:12 +02:00
|
|
|
#include "settings_telemetry.h"
|
2019-09-04 18:26:26 +02:00
|
|
|
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/comUtils/comUtils.h>
|
|
|
|
|
#include <common/display/dpi_aware.h>
|
2024-10-24 22:04:32 +02:00
|
|
|
#include <common/Telemetry/EtwTrace/EtwTrace.h>
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/notifications/notifications.h>
|
|
|
|
|
#include <common/notifications/dont_show_again.h>
|
2020-11-20 11:34:34 +03:00
|
|
|
#include <common/updating/installer.h>
|
2020-10-20 01:27:24 +03:00
|
|
|
#include <common/updating/updating.h>
|
2021-05-21 13:32:34 +03:00
|
|
|
#include <common/updating/updateState.h>
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/utils/appMutex.h>
|
|
|
|
|
#include <common/utils/elevation.h>
|
2021-06-29 13:06:12 +03:00
|
|
|
#include <common/utils/os-detect.h>
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/utils/processApi.h>
|
|
|
|
|
#include <common/utils/resources.h>
|
2025-01-16 15:17:34 +00:00
|
|
|
#include <common/utils/clean_video_conference.h>
|
2020-02-20 17:04:56 +03:00
|
|
|
|
2021-06-14 12:55:59 +03:00
|
|
|
#include "UpdateUtils.h"
|
|
|
|
|
#include "ActionRunnerUtils.h"
|
2020-02-20 17:04:56 +03:00
|
|
|
|
|
|
|
|
#include <winrt/Windows.System.h>
|
2020-02-04 19:41:00 +03:00
|
|
|
|
2020-06-11 10:09:06 +02:00
|
|
|
#include <Psapi.h>
|
|
|
|
|
#include <RestartManager.h>
|
Super resolution with AI for image resizer (#42331)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
From WinAppSDK 1.8, microsoft announced a new feature AI Imaging. We can
use this ability to enhance our image resizer tools to support scale up
the image resolution by AI.
Doc:
https://learn.microsoft.com/en-us/windows/ai/apis/imaging#what-can-i-do-with-image-super-resolution
Target:
1. Add a new config to control use AI or not.
2. Support model download in image resizer.
3. Auto detect if user's computer support AI feature, if not, do not
show the AI related config.
4. Switch the control part if user enable/disable ai feature.
Demo:
Model not ready, user need to download the model:
<img width="694" height="625" alt="image"
src="https://github.com/user-attachments/assets/8079f047-71fa-4abf-b266-003f74cc5d3e"
/>
Model ready:
<img width="543" height="589" alt="image"
src="https://github.com/user-attachments/assets/952eafc6-0af6-4bea-88d0-0724532f4fac"
/>
User's computer doesn't support AI feature (x86 machine)
<img width="685" height="531" alt="image"
src="https://github.com/user-attachments/assets/522ba300-1505-46a2-a29b-3e8e71c49cdd"
/>
Note: **This feature only support for Arm Windows with the latest
Windows version.**
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: moooyo <lengyuchn@gmail.com>
Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
2025-12-15 09:42:49 +08:00
|
|
|
#include <shellapi.h>
|
2020-09-21 12:44:16 +02:00
|
|
|
#include "centralized_kb_hook.h"
|
2021-09-23 14:23:22 +01:00
|
|
|
#include "centralized_hotkeys.h"
|
2026-01-07 16:38:09 +08:00
|
|
|
#include "quick_access_host.h"
|
Super resolution with AI for image resizer (#42331)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
From WinAppSDK 1.8, microsoft announced a new feature AI Imaging. We can
use this ability to enhance our image resizer tools to support scale up
the image resolution by AI.
Doc:
https://learn.microsoft.com/en-us/windows/ai/apis/imaging#what-can-i-do-with-image-super-resolution
Target:
1. Add a new config to control use AI or not.
2. Support model download in image resizer.
3. Auto detect if user's computer support AI feature, if not, do not
show the AI related config.
4. Switch the control part if user enable/disable ai feature.
Demo:
Model not ready, user need to download the model:
<img width="694" height="625" alt="image"
src="https://github.com/user-attachments/assets/8079f047-71fa-4abf-b266-003f74cc5d3e"
/>
Model ready:
<img width="543" height="589" alt="image"
src="https://github.com/user-attachments/assets/952eafc6-0af6-4bea-88d0-0724532f4fac"
/>
User's computer doesn't support AI feature (x86 machine)
<img width="685" height="531" alt="image"
src="https://github.com/user-attachments/assets/522ba300-1505-46a2-a29b-3e8e71c49cdd"
/>
Note: **This feature only support for Arm Windows with the latest
Windows version.**
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: moooyo <lengyuchn@gmail.com>
Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
2025-12-15 09:42:49 +08:00
|
|
|
#include "ai_detection.h"
|
|
|
|
|
#include <common/utils/package.h>
|
2020-06-11 10:09:06 +02:00
|
|
|
|
2019-09-04 18:26:26 +02:00
|
|
|
#if _DEBUG && _WIN64
|
|
|
|
|
#include "unhandled_exception_handler.h"
|
|
|
|
|
#endif
|
2020-11-18 12:15:14 +02:00
|
|
|
#include <common/logger/logger.h>
|
2021-03-25 12:26:11 +03:00
|
|
|
#include <common/SettingsAPI/settings_helpers.h>
|
|
|
|
|
#include <runner/settings_window.h>
|
|
|
|
|
#include <common/utils/process_path.h>
|
2020-12-15 15:16:09 +03:00
|
|
|
#include <common/utils/winapi_error.h>
|
|
|
|
|
#include <common/utils/window.h>
|
2021-03-25 12:26:11 +03:00
|
|
|
#include <common/version/version.h>
|
2022-08-23 22:32:45 +02:00
|
|
|
#include <common/utils/string_utils.h>
|
2024-01-18 16:18:17 +01:00
|
|
|
#include <common/utils/gpo.h>
|
2022-11-29 14:10:48 +00:00
|
|
|
|
|
|
|
|
// disabling warning 4458 - declaration of 'identifier' hides class member
|
|
|
|
|
// to avoid warnings from GDI files - can't add winRT directory to external code
|
|
|
|
|
// in the Cpp.Build.props
|
|
|
|
|
#pragma warning(push)
|
|
|
|
|
#pragma warning(disable : 4458)
|
2021-06-29 13:06:12 +03:00
|
|
|
#include <gdiplus.h>
|
2022-11-29 14:10:48 +00:00
|
|
|
#pragma warning(pop)
|
2019-09-04 18:26:26 +02:00
|
|
|
|
2020-02-18 18:11:01 +03:00
|
|
|
namespace
|
|
|
|
|
{
|
2020-03-24 17:17:25 +03:00
|
|
|
const wchar_t PT_URI_PROTOCOL_SCHEME[] = L"powertoys://";
|
2020-10-22 19:02:59 +03:00
|
|
|
const wchar_t POWER_TOYS_MODULE_LOAD_FAIL[] = L"Failed to load "; // Module name will be appended on this message and it is not localized.
|
2020-02-18 18:11:01 +03:00
|
|
|
}
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
void chdir_current_executable()
|
|
|
|
|
{
|
|
|
|
|
// Change current directory to the path of the executable.
|
|
|
|
|
WCHAR executable_path[MAX_PATH];
|
|
|
|
|
GetModuleFileName(NULL, executable_path, MAX_PATH);
|
|
|
|
|
PathRemoveFileSpec(executable_path);
|
|
|
|
|
if (!SetCurrentDirectory(executable_path))
|
|
|
|
|
{
|
2020-10-22 19:02:59 +03:00
|
|
|
show_last_error_message(L"Change Directory to Executable Path", GetLastError(), L"PowerToys - runner");
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
Super resolution with AI for image resizer (#42331)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
From WinAppSDK 1.8, microsoft announced a new feature AI Imaging. We can
use this ability to enhance our image resizer tools to support scale up
the image resolution by AI.
Doc:
https://learn.microsoft.com/en-us/windows/ai/apis/imaging#what-can-i-do-with-image-super-resolution
Target:
1. Add a new config to control use AI or not.
2. Support model download in image resizer.
3. Auto detect if user's computer support AI feature, if not, do not
show the AI related config.
4. Switch the control part if user enable/disable ai feature.
Demo:
Model not ready, user need to download the model:
<img width="694" height="625" alt="image"
src="https://github.com/user-attachments/assets/8079f047-71fa-4abf-b266-003f74cc5d3e"
/>
Model ready:
<img width="543" height="589" alt="image"
src="https://github.com/user-attachments/assets/952eafc6-0af6-4bea-88d0-0724532f4fac"
/>
User's computer doesn't support AI feature (x86 machine)
<img width="685" height="531" alt="image"
src="https://github.com/user-attachments/assets/522ba300-1505-46a2-a29b-3e8e71c49cdd"
/>
Note: **This feature only support for Arm Windows with the latest
Windows version.**
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: moooyo <lengyuchn@gmail.com>
Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
2025-12-15 09:42:49 +08:00
|
|
|
// Detect AI capabilities by calling ImageResizer in detection mode.
|
|
|
|
|
// This runs in a background thread to avoid blocking the main startup.
|
|
|
|
|
// ImageResizer writes the result to a cache file that it reads on normal startup.
|
|
|
|
|
void DetectAiCapabilitiesAsync(bool skipSettingsCheck)
|
|
|
|
|
{
|
|
|
|
|
std::thread([skipSettingsCheck]() {
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// Check if ImageResizer module is enabled (skip if called from apply_general_settings)
|
|
|
|
|
if (!skipSettingsCheck)
|
|
|
|
|
{
|
|
|
|
|
auto settings = PTSettingsHelper::load_general_settings();
|
|
|
|
|
if (json::has(settings, L"enabled", json::JsonValueType::Object))
|
|
|
|
|
{
|
|
|
|
|
auto enabledModules = settings.GetNamedObject(L"enabled");
|
|
|
|
|
if (json::has(enabledModules, L"Image Resizer", json::JsonValueType::Boolean))
|
|
|
|
|
{
|
|
|
|
|
bool isEnabled = enabledModules.GetNamedBoolean(L"Image Resizer", false);
|
|
|
|
|
if (!isEnabled)
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"ImageResizer module is disabled, skipping AI detection");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get ImageResizer.exe path (located in WinUI3Apps folder)
|
|
|
|
|
std::wstring imageResizerPath = get_module_folderpath();
|
|
|
|
|
imageResizerPath += L"\\WinUI3Apps\\PowerToys.ImageResizer.exe";
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(imageResizerPath))
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"ImageResizer.exe not found at {}, skipping AI detection", imageResizerPath);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Logger::info(L"Starting AI capability detection via ImageResizer");
|
|
|
|
|
|
|
|
|
|
// Call ImageResizer --detect-ai
|
|
|
|
|
SHELLEXECUTEINFO sei = { sizeof(sei) };
|
|
|
|
|
sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
|
|
|
|
|
sei.lpFile = imageResizerPath.c_str();
|
|
|
|
|
sei.lpParameters = L"--detect-ai";
|
|
|
|
|
sei.nShow = SW_HIDE;
|
|
|
|
|
|
|
|
|
|
if (ShellExecuteExW(&sei))
|
|
|
|
|
{
|
|
|
|
|
// Wait for detection to complete (with timeout)
|
|
|
|
|
DWORD waitResult = WaitForSingleObject(sei.hProcess, 30000); // 30 second timeout
|
|
|
|
|
CloseHandle(sei.hProcess);
|
|
|
|
|
|
|
|
|
|
if (waitResult == WAIT_OBJECT_0)
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"AI capability detection completed successfully");
|
|
|
|
|
}
|
|
|
|
|
else if (waitResult == WAIT_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"AI capability detection timed out");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"AI capability detection wait failed");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::warn(L"Failed to launch ImageResizer for AI detection, error: {}", GetLastError());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (const std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
Logger::error("Exception during AI capability detection: {}", e.what());
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
Logger::error("Unknown exception during AI capability detection");
|
|
|
|
|
}
|
|
|
|
|
}).detach();
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-27 19:53:29 +03:00
|
|
|
inline wil::unique_mutex_nothrow create_msi_mutex()
|
2020-02-18 18:11:01 +03:00
|
|
|
{
|
2020-07-27 19:53:29 +03:00
|
|
|
return createAppMutex(POWERTOYS_MSI_MUTEX_NAME);
|
2020-02-18 18:11:01 +03:00
|
|
|
}
|
|
|
|
|
|
2021-09-29 12:54:05 +02:00
|
|
|
void open_menu_from_another_instance(std::optional<std::string> settings_window)
|
2020-02-21 11:12:04 +01:00
|
|
|
{
|
2020-07-27 19:53:29 +03:00
|
|
|
const HWND hwnd_main = FindWindowW(L"PToyTrayIconWindow", nullptr);
|
[Settings]Adding a Dashboard Panel (#29023)
* Dashboard: modifying page content + adding SW version button.
* Visual tweaks and minor viewmodel changes
* Updated spacing
* Adding Settings icon
* Settiing the Dashboard page as the default one. Adding functionality to switch to settings pages from the Dashboard page. Localizing texts.
* fixing csproj file
* Reimplementing Active modules handling, showing only the active modules (and not having invisible inactive modules).
* Removing unneccessary binding
* Fix text wrapping
* Adding Registry previewer launch, adding activation mode for FindMyMouse and QuickAccent, modify File Locksmith description.
* Spell checker fix typo
* Adding GPO-blocked state, modifying buttons: adding description, icon.
* Modifying dashboard button layout
* Use SettingsCard instead of button
* Restructuring the dashboard panel
* Removing togglebuttons from the left panel. Showing only active modules. Adding key remappings (to KBM)
* Removing settings buttons, removing descriptions, icons from buttons. Add update of remapped keys, shortcuts.
* Refactoring dashboard
* Making list always visible and fixing scrolling behavior
* Adding background gradient to cards
* Removing keyboard manager's key mappings, minor changes in texts, fixing enabled state when GPO-enabled.
* Use ListView instead of ItemsRepeater
* Updates
* removing right panel with all modules. Extending "left" panel with toggleswitches, showing all modules.
* Separate lists
* Adding Flyout with key remappings for KBM module, adding IsLocked property, icons
* Visual tweaks
* Tweaks
* Fixing lock icon margin
* Minor fixes.
* Removing unused resources
* Make Dashboard default when coming from the OOBE General
* Removed the Previous, Next Layout buttons from FancyZones. Added activation information
---------
Co-authored-by: Niels Laute <niels.laute@live.nl>
2023-10-20 14:23:25 +02:00
|
|
|
LPARAM msg = static_cast<LPARAM>(ESettingsWindowNames::Dashboard);
|
2023-06-07 06:42:51 -04:00
|
|
|
if (settings_window.has_value() && settings_window.value() != "")
|
2021-09-29 12:54:05 +02:00
|
|
|
{
|
|
|
|
|
msg = static_cast<LPARAM>(ESettingsWindowNames_from_string(settings_window.value()));
|
|
|
|
|
}
|
|
|
|
|
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);
|
2025-05-26 05:03:35 -04:00
|
|
|
SetForegroundWindow(hwnd_main); // Bring the settings window to the front
|
2020-02-21 11:12:04 +01:00
|
|
|
}
|
|
|
|
|
|
2024-01-18 16:18:17 +01:00
|
|
|
int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe, bool showRestartNotificationAfterUpdate)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2024-01-18 16:18:17 +01:00
|
|
|
Logger::info("Runner is starting. Elevated={} openOobe={} openScoobe={} showRestartNotificationAfterUpdate={}", isProcessElevated, openOobe, openScoobe, showRestartNotificationAfterUpdate);
|
2019-12-26 17:26:11 +01:00
|
|
|
DPIAware::EnableDPIAwarenessForThisProcess();
|
|
|
|
|
|
|
|
|
|
#if _DEBUG && _WIN64
|
|
|
|
|
//Global error handlers to diagnose errors.
|
2022-07-01 10:09:41 -04:00
|
|
|
//We prefer this not to show any longer until there's a bug to diagnose.
|
2019-12-26 17:26:11 +01:00
|
|
|
//init_global_error_handlers();
|
|
|
|
|
#endif
|
|
|
|
|
Trace::RegisterProvider();
|
2026-01-08 14:23:59 +08:00
|
|
|
|
|
|
|
|
// Load settings from file before reading them
|
|
|
|
|
load_general_settings();
|
|
|
|
|
auto const settings = get_general_settings();
|
|
|
|
|
start_tray_icon(isProcessElevated, settings.showThemeAdaptiveTrayIcon);
|
|
|
|
|
|
|
|
|
|
if (settings.enableQuickAccess)
|
2026-01-07 16:38:09 +08:00
|
|
|
{
|
|
|
|
|
QuickAccessHost::start();
|
|
|
|
|
}
|
2026-01-08 14:23:59 +08:00
|
|
|
update_quick_access_hotkey(settings.enableQuickAccess, settings.quickAccessShortcut);
|
|
|
|
|
set_tray_icon_visible(settings.showSystemTrayIcon);
|
2020-09-21 12:44:16 +02:00
|
|
|
CentralizedKeyboardHook::Start();
|
2020-02-18 18:11:01 +03:00
|
|
|
|
|
|
|
|
int result = -1;
|
2019-12-26 17:26:11 +01:00
|
|
|
try
|
|
|
|
|
{
|
2024-01-18 16:18:17 +01:00
|
|
|
if (!openOobe && showRestartNotificationAfterUpdate)
|
2023-07-25 12:27:53 +01:00
|
|
|
{
|
2023-07-28 17:23:54 +02:00
|
|
|
std::thread{
|
|
|
|
|
[] {
|
|
|
|
|
// Wait a bit, because Windows has a delay until it picks up toast notification registration in the registry
|
|
|
|
|
Sleep(10000);
|
|
|
|
|
Logger::info("Showing toast notification asking to restart PC");
|
|
|
|
|
notifications::show_toast(GET_RESOURCE_STRING(IDS_PT_VERSION_CHANGE_ASK_FOR_COMPUTER_RESTART).c_str(), L"PowerToys");
|
|
|
|
|
}
|
|
|
|
|
}.detach();
|
2023-07-25 12:27:53 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-12 10:59:10 +03:00
|
|
|
std::thread{ [] {
|
2021-06-14 12:55:59 +03:00
|
|
|
PeriodicUpdateWorker();
|
2020-03-12 10:59:10 +03:00
|
|
|
} }.detach();
|
|
|
|
|
|
Super resolution with AI for image resizer (#42331)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
From WinAppSDK 1.8, microsoft announced a new feature AI Imaging. We can
use this ability to enhance our image resizer tools to support scale up
the image resolution by AI.
Doc:
https://learn.microsoft.com/en-us/windows/ai/apis/imaging#what-can-i-do-with-image-super-resolution
Target:
1. Add a new config to control use AI or not.
2. Support model download in image resizer.
3. Auto detect if user's computer support AI feature, if not, do not
show the AI related config.
4. Switch the control part if user enable/disable ai feature.
Demo:
Model not ready, user need to download the model:
<img width="694" height="625" alt="image"
src="https://github.com/user-attachments/assets/8079f047-71fa-4abf-b266-003f74cc5d3e"
/>
Model ready:
<img width="543" height="589" alt="image"
src="https://github.com/user-attachments/assets/952eafc6-0af6-4bea-88d0-0724532f4fac"
/>
User's computer doesn't support AI feature (x86 machine)
<img width="685" height="531" alt="image"
src="https://github.com/user-attachments/assets/522ba300-1505-46a2-a29b-3e8e71c49cdd"
/>
Note: **This feature only support for Arm Windows with the latest
Windows version.**
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: moooyo <lengyuchn@gmail.com>
Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
2025-12-15 09:42:49 +08:00
|
|
|
// Start AI capability detection in background (Windows 11+ only)
|
|
|
|
|
// AI Super Resolution is not supported on Windows 10
|
|
|
|
|
// This calls ImageResizer --detect-ai which writes result to cache file
|
|
|
|
|
if (package::IsWin11OrGreater())
|
|
|
|
|
{
|
|
|
|
|
DetectAiCapabilitiesAsync();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"AI capability detection skipped: Windows 10 does not support AI Super Resolution");
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-14 12:55:59 +03:00
|
|
|
std::thread{ [] {
|
|
|
|
|
if (updating::uninstall_previous_msix_version_async().get())
|
|
|
|
|
{
|
|
|
|
|
notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L"PowerToys");
|
|
|
|
|
}
|
|
|
|
|
} }.detach();
|
2020-02-18 18:11:01 +03:00
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
chdir_current_executable();
|
2025-01-16 15:17:34 +00:00
|
|
|
|
|
|
|
|
// We deprecated a utility called Video Conference Mute, which registered itself as a video input device.
|
|
|
|
|
// When running elevated, we try to clean up the device registration from previous installations.
|
|
|
|
|
// This is done here too because a user-scope installer won't be able to remove the driver registration due to lack of permissions.
|
|
|
|
|
if (isProcessElevated)
|
|
|
|
|
{
|
|
|
|
|
clean_video_conference();
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-06 06:33:08 -10:00
|
|
|
// Load PowerToys DLLs
|
2020-06-22 13:01:33 +03:00
|
|
|
|
2021-06-29 13:06:12 +03:00
|
|
|
std::vector<std::wstring_view> knownModules = {
|
2023-07-20 00:12:46 +01:00
|
|
|
L"PowerToys.FancyZonesModuleInterface.dll",
|
|
|
|
|
L"PowerToys.powerpreview.dll",
|
Fix: File explorer preview didn't work with per-user installation (#40314)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This Bug started when the Win11 context menu integration was first
introduced by Image Resizer in version v0.60.0.
Move Image Resizer to the WinUI3Apps folder to fix file preview issue
when PowerToys is installed on a non-C:\Program Files.
This aligns with the current structure used by File Locksmith and
PowerRename, which are not WinUI 3 apps either, but are already located
there.
### Root Cause:
When registering an MSIX package, the Windows API adds certain user
permissions to the installation folders. Since Image Resizer was
previously placed under the main PowerToys directory, these permission
changes could prevent Explorer from loading its preview handler properly
in per-user scenarios.

Interestingly, this issue only affects per-user installs, not
machine-wide installs (e.g., to Program Files), even though both
locations receive additional permissions. The exact reason is still
unclear and requires further investigation.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] **Closes:** #24384 #29644 #32113 #34139 #37866 #40345
- [ ] **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
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-07-07 09:41:19 +08:00
|
|
|
L"WinUI3Apps/PowerToys.ImageResizerExt.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"PowerToys.KeyboardManager.dll",
|
|
|
|
|
L"PowerToys.Launcher.dll",
|
|
|
|
|
L"WinUI3Apps/PowerToys.PowerRenameExt.dll",
|
2026-05-21 17:27:52 +02:00
|
|
|
L"WinUI3Apps/PowerToys.ShortcutGuideModuleInterface.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"PowerToys.ColorPicker.dll",
|
|
|
|
|
L"PowerToys.AwakeModuleInterface.dll",
|
|
|
|
|
L"PowerToys.FindMyMouse.dll",
|
|
|
|
|
L"PowerToys.MouseHighlighter.dll",
|
Ready for Review - [Mouse Jump] - port upstream WinUI3 code to Mouse Jump (microsoft#48290) (#48393)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Changes for #48290 to convert Mouse Jump to a WinUI app and remove all
remaining dependencies on WinForms, based on work already done in the
original "FancyMouse" project
(https://github.com/mikeclayton/FancyMouse).
## Notes for reviewers
* the new WinUI build of the app is output into the "/WinUI3Apps"
subfolder
* there's 2 new assemblies that need to be added to the installation as
well - MouseJump.HotKeys.dll and MouseJump.Models.dll. I'm not sure how
to add those to the installer for signing / shipping...
---
### Summary of changes
* New thumbnail layout and rendering code
* WinUI rewrite (winforms version still committed)
* MouseJump.Kicker (dev launch tool)
* CsWin32 for interop
* New assemblies - code reorganised
---
### 1. New layout code
Incorporates latest FancyMouse core layout and rendering logic into
Mouse Jump:
* includes **support** for multiple devices in layout algorithms
* preview still only shows local machine though
* prerequisite for long-term goal #34126
<img width="650" height="709" alt="image"
src="https://github.com/user-attachments/assets/9d1d996d-ed05-4471-b8a5-bd93442f70dc"
/>
### 2. WinUI rewrite
Port latest stable FancyMouse WinUI implementation into Mouse Jump.
Existing WinForms UI left in-situ side-by-side for now - easy to delete
if not needed.
### 3. MouseJump.Kicker
A small dev utility to start Mouse Jump without needing to build the
runner project:
<img width="283" height="274" alt="image"
src="https://github.com/user-attachments/assets/c81bb3f5-5008-48ce-8bc0-eef18413dee6"
/>
### 4. Cswin32 for interop
All win32 interop is now accessed via CsWin32 bindings.
The original win32 bindings were heavily influenced by CsWin32 generated
code (e.g. ```BOOL```, ```HWND```, etc structs), so there's not actually
much change other than deleting a lot of boilerplate code.
### 5. New assemblies
Some code has been reorganised into new assemblies to make it easier to
keep Mouse Jump in sync with upstream FancyMouse
* MouseJump.HotKeys
* MouseJump.Models
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes #48290
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized
- all ui strings come from Resources.resw
- [x] **Dev docs:** Added/updated
- no changes required
- [x] **New binaries:** Added on the required places
- no changes required
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [x] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [x] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [x] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [x] **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
- no changes required
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- **Workflow tests**
- [x] Automated tests passing locally
- [x] Minimal actions workflow (spelling check) passing for PR
- [ ] Full actions workflow (msbuild) passing for PR
- **UI tests**
- [x] Happy path
- [x] preview image appears when activated
- [x] clicking the preview image moves the mouse cursor to the correct
location
- [x] right-click dismisses the preview image without moving the mouse
- [x] pressing escape dismisses the preview image without moving the
mouse
- [x] left or right clicking another application / desktop dismisses the
preview image without moving the mouse
- [x] Works on multiple monitors with different dpi scaling settings
(e.g. 100% vs 150%)
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1411869418
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1412834413
- [x] Handling negative coordinates on non-primary monitors if higher or
"lefter" than primary monitor
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1404931694
- [x] Mouse crosshair moves when Mouse Jump moves the cursor (mouse
clicks *and* keyboard shortcuts)
* #24523
* #24527
- [x] Activating when the preview window is already visible moves the
form to the new mouse position
- [x] Number and key shortcuts (1-9, Home / End, Left / Right Arrow)
jump to the appropriate monitor
- [x] Number-pad shortcuts (1-9 jump to the appropriate monitor
- **Settings tests**
- [x] Changing thumbnail size settings updates the size of the thumbnail
- [x] Changing preview type between Compact, Bezelled and Custom shows
the correct preview type
- [x] Changing custom preview settings shows the correct settings
- [ ] Launching with settings version 1.0 upgrades settings to version
1.1, with "Bezelled" as the default style and the "Custom" settings
preconfigured to match "Bezelled"
- **Lifecycle tests**
- [x] Starting PowerToys Runner launches MouseJump exe when enabled, and
not when disabled
- [x] Enabling / disabling Mouse Jump in settings starts / stops
MouseJump exe
- [x] Exiting PowerToys Runner stops MouseJump exe
- [x] Killing runner exe via Task Manager stops MouseJump exe
- [x] Stopping Visual Studio local debug run stops MouseJump exe
- note - runner needs to be in *non*-admin mode otherwise Visual Studio
debugger disconnects at launch
- [x] Hotkey and size settings are automatically reloaded when config
file is modified from Settings UI
- [ ] ~~Hotkey and size settings are automatically reloaded when config
file is modified manually (e.g. in notepad) while runner and
MouseJumpUI.exe are running~~
- **[Internal Test
Suite](https://github.com/microsoft/PowerToys/blob/5bc7201ae2b75b53d3a4bc35119c867ecf71c5f6/doc/releases/tests-checklist-template.md#mouse-utils)**
- [x] Enable Mouse Jump. Then:
- [x] Press the activation shortcut and verify the screens preview
appears.
- [x] Change activation shortcut and verify that new shortcut triggers
Mouse Jump.
- [x] Click around the screen preview and ensure that mouse cursor
jumped to clicked location.
- [x] Reorder screens in Display settings and confirm that Mouse Jump
reflects the change and still works correctly.
- [x] Change scaling of screens and confirm that Mouse Jump still works
correctly.
- [ ] Unplug additional monitors and confirm that Mouse Jump still works
correctly.
- [x] Disable Mouse Jump and verify that the module is not activated
when you press the activation shortcut.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: moooyo <42196638+moooyo@users.noreply.github.com>
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85
2026-08-07 06:34:15 +01:00
|
|
|
L"WinUI3Apps/PowerToys.MouseJump.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"PowerToys.AlwaysOnTopModuleInterface.dll",
|
|
|
|
|
L"PowerToys.MousePointerCrosshairs.dll",
|
2025-11-05 03:28:25 -08:00
|
|
|
L"PowerToys.CursorWrap.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"PowerToys.PowerAccentModuleInterface.dll",
|
|
|
|
|
L"PowerToys.PowerOCRModuleInterface.dll",
|
2024-05-09 10:32:03 -04:00
|
|
|
L"PowerToys.AdvancedPasteModuleInterface.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"WinUI3Apps/PowerToys.FileLocksmithExt.dll",
|
|
|
|
|
L"WinUI3Apps/PowerToys.RegistryPreviewExt.dll",
|
|
|
|
|
L"WinUI3Apps/PowerToys.MeasureToolModuleInterface.dll",
|
2024-09-19 09:12:24 -07:00
|
|
|
L"WinUI3Apps/PowerToys.NewPlus.ShellExtension.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"WinUI3Apps/PowerToys.HostsModuleInterface.dll",
|
|
|
|
|
L"WinUI3Apps/PowerToys.Peek.dll",
|
2023-10-20 16:28:07 +02:00
|
|
|
L"WinUI3Apps/PowerToys.EnvironmentVariablesModuleInterface.dll",
|
2023-07-20 00:12:46 +01:00
|
|
|
L"PowerToys.MouseWithoutBordersModuleInterface.dll",
|
2023-08-10 10:46:33 +01:00
|
|
|
L"PowerToys.CropAndLockModuleInterface.dll",
|
2024-01-03 07:43:42 -08:00
|
|
|
L"PowerToys.CmdNotFoundModuleInterface.dll",
|
[New Module] Workspaces (#34324)
* spell checker
* Adding OOBE Projects page
* changed the default hotkey
* module interface
* rename projects editor
* bug report tool
* installer
* gpo
* exit event constant
* extend search for projects by search over the containing apps' names
* [Projects] fix grammatical issue #43 (1 app - many apps)
* [Projects] Editor: Main page: fix layout if there are many apps, launch button not disappearing on the right side
* dsc
* github
* pipeline
* guid prefix
* [Projects] fixing general settings gpo handling in runner + minor changes
* arm build fix
* Do not allow saving project if name or applist is empty. Also minor UI changes
* version
* editor version
* spellcheck
* editor dll signing
* update projects names to filter them out
* shortcut saving fix
* [Projects] Editor: brining the highlighted app's icon into the foreground. + minor UI fixes
* spell checker
* spellcheck
* [Projects] re-implementing icon size calculation to have similar sized icons for every app.
* [projects] Adding info message for cases: there are no projects or no results for the search
* [Projects] Adding Edit button to the popup. + minor changes
* [Projects] Making popup having rounded corners
* changed "no projects" text color and position
* remove opening the first proj
* fix placing windows of the same app in the project
* [Projects] bringing back the breadcrumb on the editor page. Make it clickable.
* [Projects] optimizing click handlers
* [Projects] Removing not selected apps on save
* moved on thread executor to common
* moved display utils
* added convert rect
* unsigned monitor number
* set awareness
* app placement
* [Projects] Re-implementing preview drawing - one common image
* [Projects] fix boundary calculation, use DPI aware values
* fix launching with command line args
* Fix ARM64 CI build
* launch packaged apps using names when possible
* spell-check
* update packaged apps path
* projects editor single instance
* [Projects] Add Select all checkbox, Delete selected button
* Add Checkbox for per monitor selection
* modifying highlight in preview
* spell checker
* logs
* exclude help windows
https://github.com/JaneaSystems/PowerToys-DevProjects/issues/49
* Add intermediate step to project creation
* minor bugfix
* mutex fix
* modifying highlight for minimized apps
* Fixing bug: re-draw the preview on app deletion in the editor
* Adding helper class for getting the right bounds for screens
* spell checker
* spell checker
* Minor fixes in the capture dialog
* get dpi unaware screen bounds
* refactoring: added utils
* changed window filter
https://github.com/JaneaSystems/PowerToys-DevProjects/issues/2
* clean up
* refactoring
* projects common lib
* localizable default project prefix
* launcher resources
* clean up
* change snapshot project saving
https://github.com/JaneaSystems/PowerToys-DevProjects/issues/14
* changed project data
https://github.com/JaneaSystems/PowerToys-DevProjects/issues/14
* changed project creation save-cancel handles
https://github.com/JaneaSystems/PowerToys-DevProjects/issues/14
* spell-check
* Remove checkboxes, delete feature
* remove unused from the project
* get command line args in the snapshot
* minimized settings snap fix
* set window property after launching
* FZ: ignore projects launched windows
* Implementing major new features: remove button, position manipulation, arguments, admin, minimized, maximized
* modifying colors
* launcher project filters
* clean up
* Hide Admin checkbox
* hide WIP
* spell-check
* Revert "Hide Admin checkbox"
This reverts commit 3036df9d7fe48de6418b0ebeff6422d535cb25e2.
* get app elevated property
* Implementing Launch and Edit feature
* fixing: update of listed projects on the main page after hitting save in editor
* Fix for packaged app's icons
* fixing scroll speed issue
* change scroll speed to 15
* launch elevated apps
* minor fixes
* minor fix
* enhancing shortcut handling
* can-launch-elevated check
* projects module interface telemetry
* Implementing store of setting "order by".
* minor string correction
* moved projects data parsing
* telemetry
* add move apps checkbox
* notification about elevated apps
* restart unelevated
* move existing windows
* keep opened windows at the same positions
* handle powertoys settings
* use common theme
* fix corrupted data: project id and monitor id
* project launch on "launch and edit"
* clean up
* show screen numbers instead of monitor names
* launcher error messages
* fix default shortcut
* Adding launch button to projects settings, dashboard and flyout
* Adding new app which is launched when launching a project. It shows the status of the launch process
* spell checker
* Renaming Projects to App Layouts. Replacing only string values, not the variable names
* Re-ordering modules after Renaming Projects + spell checker
* setting window size according to the screen (making it bigger)
* commenting out feature "move apps if exist"
* spell checker
* Add ProjectsLauncherUI to signing
* opening apps in minimized state which are placed on a monitor, which is not found at the moment of launching
* consistent file name
* removed unused sln
* telemetry: create event
* WindowPosition comparison
* telemetry: edit event
* fix muted Launch as admin checkbox
* telemetry: delete event
* updated Edit telemetry event
* added invoke point to launcher args
* added utils
* parse invoke point
* replaced tuple with struct
* telemetry: launch event
* MonitorRect comparison
* resources
* rename: folders
* remove outdated
* rename: window property
* rename: files and folders
* rename: common data structures
* rename: telemetry namespace
* rename: workspaces data
* rename ProjectsLib -> WorkspacesLib
* rename: gpo
* rename: settings
* rename: launcher UI
* rename: other
* rename: pt run
* rename: fz
* rename: module interface
* rename: icon
* rename: snapshot tool
* rename: editor
* rename: common files
* rename: launcher
* rename: editor resources
* fix empty file crash
* rename: json
* rename: module interface
* fix custom actions build
* added launch editor event constant
* xaml formatting
* Add missing method defition to interop::Constants idl
Remove Any CPU config
* more .sln cleanup
* [Run][PowerToys] Fix Workspaces utility (#34336)
polished workspaces utility
* build fix - align CppWinRT version
* address PR comment: fix isdigit
* indentation
* address PR comment: rename function
* address PR comment: changed version for workspaces and revision
* added supported version definition
* addressPR comment: use BringToForeground
* address PR comments: updated projects
* address PR comment: uncomment gpo in settings
* address PR comment: rename oobe view
* update OOBE image with current module name
* moved AppUtils
* launching with AppUserModel.ID
* fixed module order in settings
* fix xaml formatting
* [Workspaces] Close launcher if there are failed launches. Plus adding new spinner gif
* fix topmost LauncherUI
* clean up
* UI closing
* BugReportTool - omit cmd arg data
* Delete icon on workspace removal
* Adding cancellation to launcher UI.
* reordered launching
* fix terminating UI
* Removing old shortcut on workspace renaming
* Sentence case labels
* get process path without waiting
* comment out unused
* remove unused argument
* logs
* New icon
* fix launch and edit for the new project
* fix launch and edit: save new project
* Update exe icons
---------
Co-authored-by: donlaci <laszlo@janeasystems.com>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Stefan Markovic <stefan@janeasystems.com>
Co-authored-by: Davide Giacometti <davide.giacometti@outlook.it>
Co-authored-by: Niels Laute <niels.laute@live.nl>
2024-08-23 09:28:13 +02:00
|
|
|
L"PowerToys.WorkspacesModuleInterface.dll",
|
Add the Command Palette module (#37908)
Windows Command Palette ("CmdPal") is the next iteration of PowerToys Run. With extensibility at its core, the Command Palette is your one-stop launcher to start _anything_.
By default, CmdPal is bound to <kbd>Win+Alt+Space</kbd>.


----
This brings the current preview version of CmdPal into the upstream PowerToys repo. There are still lots of bugs to work out, but it's reached the state we're ready to start sharing it with the world. From here, we can further collaborate with the community on the features that are important, and ensuring that we've got a most robust API to enable developers to build whatever extensions they want.
Most of the built-in PT Run modules have already been ported to CmdPal's extension API. Those include:
* Installed apps
* Shell commands
* File search (powered by the indexer)
* Windows Registry search
* Web search
* Windows Terminal Profiles
* Windows Services
* Windows settings
There are a couple new extensions built-in
* You can now search for packages on `winget` and install them right from the palette. This also powers searching for extensions for the palette
* The calculator has an entirely new implementation. This is currently less feature complete than the original PT Run one - we're looking forward to updating it to be more complete for future ingestion in Windows
* "Bookmarks" allow you to save shortcuts to files, folders, and webpages as top-level commands in the palette.
We've got a bunch of other samples too, in this repo and elsewhere
### PowerToys specific notes
CmdPal will eventually graduate out of PowerToys to live as its own application, which is why it's implemented just a little differently than most other modules. Enabling CmdPal will install its `msix` package.
The CI was minorly changed to support CmdPal version numbers independent of PowerToys itself. It doesn't make sense for us to start CmdPal at v0.90, and in the future, we want to be able to rev CmdPal independently of PT itself.
Closes #3200, closes #3600, closes #7770, closes #34273, closes #36471, closes #20976, closes #14495
-----
TODOs et al
**Blocking:**
- [ ] Images and descriptions in Settings and OOBE need to be properly defined, as mentioned before
- [ ] Niels is on it
- [x] Doesn't start properly from PowerToys unless the fix PR is merged.
- https://github.com/zadjii-msft/PowerToys/pull/556 merged
- [x] I seem to lose focus a lot when I press on some limits, like between the search bar and the results.
- This is https://github.com/zadjii-msft/PowerToys/issues/427
- [x] Turned off an extension like Calculator and it was still working.
- Need to get rid of that toggle, it doesn't do anything currently
- [x] `ListViewModel.<FetchItems>` crash
- Pretty confident that was fixed in https://github.com/zadjii-msft/PowerToys/pull/553
**Not blocking / improvements:**
- Show the shortcut through settings, as mentioned before, or create a button that would open CmdPalette settings.
- When PowerToys starts, CmdPalette is always shown if enabled. That's weird when just starting PowerToys/ logging in to the computer with PowerToys auto-start activated. I think this should at least be a setting.
- Needing to double press a result for it to do the default action seems quirky. If one is already selected, I think just pressing should be enough for it to do the action.
- This is currently a setting, though we're thinking of changing the setting even more: https://github.com/zadjii-msft/PowerToys/issues/392
- There's no URI extension. Was surprised when typing a URL that it only proposed a web search.
- [x] There's no System commands extension. Was expecting to be able to quickly restart the computer by typing restart but it wasn't there.
- This is in PR https://github.com/zadjii-msft/PowerToys/pull/452
---------
Co-authored-by: joadoumie <98557455+joadoumie@users.noreply.github.com>
Co-authored-by: Jordi Adoumie <jordiadoumie@microsoft.com>
Co-authored-by: Mike Griese <zadjii@gmail.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Michael Hawker <24302614+michael-hawker@users.noreply.github.com>
Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>
Co-authored-by: Seraphima <zykovas91@gmail.com>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>
Co-authored-by: Eric Johnson <ericjohnson327@gmail.com>
Co-authored-by: Ethan Fang <ethanfang@microsoft.com>
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
2025-03-19 03:39:57 -05:00
|
|
|
L"PowerToys.CmdPalModuleInterface.dll",
|
2025-01-16 20:52:24 +00:00
|
|
|
L"PowerToys.ZoomItModuleInterface.dll",
|
[New Module] Light Switch (#41987)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This pull request introduces a new module called "Light Switch" which
allows users to automatically switch between light and dark mode on a
timer.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes: #1331
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [x] **New binaries:** Added on the required places
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [x] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [x] **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:
[#5867](https://github.com/MicrosoftDocs/windows-dev-docs-pr/pull/5867)
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
### Known bugs:
- Default settings not saving correctly when switching modes
- Issue: Sometimes when you switch from one mode to another, they are
supposed to update with new defaults but sometimes this fails for the
second variable. Potentially has to do with accessing the settings file
while another chunk of code is still updating.
- Sometimes the system looks "glitched" when switching themes
### To do:
- [x] OOBE page and assets
- [x] Logic to disable the chart when no location has been selected
- [x] Localization
### How to and what to test
Grab the latest installer from the pipeline below for your architecture
and install PowerToys from there.
- Toggle theme shortcutSystem only, Apps only, Both system and apps
selected
- Does changing the values on the settings page update the settings
file? %LOCALAPPDATA%/Microsoft/PowerToys/LightSwitch/settings.json
- Manual mode: System only, Apps only, Both system and apps selected
- Sunrise modes: Are the times accurate?
- If you manage to let this run through sunset/rise does the theme
change?
- Set your theme to change within the next minute using manual mode and
set your device to sleepOpen your device and login once the time you set
has passed. --> Do your settings resync once the next minute ticks after
logging back into your device?
- Disable the service and ensure the tasks actually ends.
- While the module is disabled:
- Make sure the shortcut no longer works
- Make sure the last time you set doesn't trigger a theme change
- Bonus: Toggle GPO Configuration and make sure you are unable to enable
the module
---------
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
2025-10-06 16:44:07 -04:00
|
|
|
L"PowerToys.LightSwitchModuleInterface.dll",
|
2026-04-10 15:14:41 +08:00
|
|
|
L"PowerToys.PowerDisplayModuleInterface.dll",
|
2026-04-15 15:13:56 +08:00
|
|
|
L"PowerToys.GrabAndMoveModuleInterface.dll",
|
2026-07-30 22:42:05 -07:00
|
|
|
L"PowerToys.AltWindowCycle.dll",
|
2019-12-26 17:26:11 +01:00
|
|
|
};
|
2020-05-08 08:23:18 -07:00
|
|
|
|
2022-12-18 11:31:43 +00:00
|
|
|
for (auto moduleSubdir : knownModules)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2020-06-22 13:01:33 +03:00
|
|
|
try
|
|
|
|
|
{
|
2021-01-08 19:26:38 +01:00
|
|
|
auto pt_module = load_powertoy(moduleSubdir);
|
|
|
|
|
modules().emplace(pt_module->get_key(), std::move(pt_module));
|
2020-06-22 13:01:33 +03:00
|
|
|
}
|
|
|
|
|
catch (...)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2020-10-22 19:02:59 +03:00
|
|
|
std::wstring errorMessage = POWER_TOYS_MODULE_LOAD_FAIL;
|
|
|
|
|
errorMessage += moduleSubdir;
|
2025-09-24 02:52:48 -07:00
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
// In debug mode, simply log the warning and continue execution.
|
|
|
|
|
// This contrasts with the past approach where developers had to build all modules
|
|
|
|
|
// without errors before debugging—slowing down quick clone-and-fix iterations.
|
|
|
|
|
Logger::warn(L"Debug mode: {}", errorMessage);
|
|
|
|
|
#else
|
|
|
|
|
// In release mode, show error dialog as before
|
2020-10-22 19:02:59 +03:00
|
|
|
MessageBoxW(NULL,
|
|
|
|
|
errorMessage.c_str(),
|
|
|
|
|
L"PowerToys",
|
|
|
|
|
MB_OK | MB_ICONERROR);
|
2025-09-24 02:52:48 -07:00
|
|
|
#endif
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Start initial powertoys
|
2021-12-07 05:50:04 -08:00
|
|
|
start_enabled_powertoys();
|
2022-02-22 11:02:08 +00:00
|
|
|
std::wstring product_version = get_product_version();
|
|
|
|
|
Trace::EventLaunch(product_version, isProcessElevated);
|
|
|
|
|
PTSettingsHelper::save_last_version_run(product_version);
|
2019-09-04 18:26:26 +02:00
|
|
|
|
2021-02-10 14:48:43 +01:00
|
|
|
if (openSettings)
|
|
|
|
|
{
|
2021-09-29 12:54:05 +02:00
|
|
|
std::optional<std::wstring> window;
|
|
|
|
|
if (!settingsWindow.empty())
|
|
|
|
|
{
|
|
|
|
|
window = winrt::to_hstring(settingsWindow);
|
|
|
|
|
}
|
2026-01-07 16:38:09 +08:00
|
|
|
open_settings_window(window);
|
2021-02-10 14:48:43 +01:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 20:56:37 +03:00
|
|
|
if (openOobe)
|
|
|
|
|
{
|
2022-02-24 14:42:29 +00:00
|
|
|
PTSettingsHelper::save_oobe_opened_state();
|
2021-03-25 12:26:11 +03:00
|
|
|
open_oobe_window();
|
2021-03-02 20:56:37 +03:00
|
|
|
}
|
2022-02-22 11:02:08 +00:00
|
|
|
else if (openScoobe)
|
|
|
|
|
{
|
|
|
|
|
open_scoobe_window();
|
|
|
|
|
}
|
2021-03-02 20:56:37 +03:00
|
|
|
|
2021-03-19 19:03:12 +02:00
|
|
|
settings_telemetry::init();
|
2019-12-26 17:26:11 +01:00
|
|
|
result = run_message_loop();
|
|
|
|
|
}
|
|
|
|
|
catch (std::runtime_error& err)
|
|
|
|
|
{
|
|
|
|
|
std::string err_what = err.what();
|
2020-01-09 18:17:42 +01:00
|
|
|
MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
|
2019-12-26 17:26:11 +01:00
|
|
|
result = -1;
|
|
|
|
|
}
|
|
|
|
|
Trace::UnregisterProvider();
|
Fix runner APPLICATION_HANG_QUIESCE: handle WM_ENDSESSION and skip blocking shutdown cleanup (#48363)
## Summary
The runner WndProc (`tray_icon_window_proc`) does not handle
`WM_QUERYENDSESSION` / `WM_ENDSESSION`, **and** its `WM_DESTROY`
teardown performs blocking cross-process cleanup. Both contribute to the
Watson failure
`APPLICATION_HANG_QUIESCE_cfffffff_PowerToys.exe!run_message_loop` on OS
shutdown, sign-out, or restart:
1. Without a `WM_ENDSESSION` handler, `DefWindowProc` returns `0`
without posting a quit message, so `run_message_loop` stays parked in
`GetMessageW` until the OS quiesce timeout (~5 s) force-terminates the
process.
2. Even once teardown starts, `WM_DESTROY` calls
`close_settings_window()`, which blocks up to 1.5 s on
`WaitForSingleObject` against `PowerToys.Settings.exe`
(`src/runner/settings_window.cpp:712`), plus
`Shell_NotifyIcon(NIM_DELETE)` during Explorer teardown. The Windows
[shutdown
guidance](https://learn.microsoft.com/windows/win32/shutdown/shutting-down)
is explicit that handlers must not block.
This PR fixes both issues for the always-on runner. Rollout to
module-owned windows is intentionally separate and tracked in #49539.
> Supersedes #48378 (same Watson bucket) by combining its
no-blocking-cleanup fix with a reusable helper and unit tests. The
cleanup-skip insight is credited to @yeelam-gordon.
Related (same failure class, different binary): #41260.
## Root cause
`src/runner/tray_icon.cpp` → `tray_icon_window_proc` had no case for
`WM_QUERYENDSESSION` / `WM_ENDSESSION`, and `WM_DESTROY` unconditionally
ran cross-process cleanup. On a full Windows session end, the OS
delivers `WM_ENDSESSION` to child applications and reaps them
independently, so the runner's waits consume the quiesce budget without
helping shutdown complete.
## Fix
### 1. Explicitly stateless helper in `src/common/utils/window.h`
`handle_stateless_session_end_message`:
- `WM_QUERYENDSESSION` → returns `TRUE`. The name makes clear that this
helper is only for processes with no unsaved user state.
- `WM_ENDSESSION(TRUE)` → calls `DestroyWindow(window)`, driving the
existing `WM_DESTROY → PostQuitMessage(0)` path so `run_message_loop`
unwinds.
- `WM_ENDSESSION(FALSE)` → leaves the window alone because another
application cancelled shutdown.
- The optional `out_system_session_ending` flag is set only when the
full Windows session is ending. `ENDSESSION_CLOSEAPP` still closes the
runner but leaves the flag false so Restart Manager requests retain
normal child-process cleanup.
Stateful modules must implement their own save/permission behavior
rather than adopt this helper. `tray_icon_window_proc` calls it at the
top of dispatch and returns immediately when the message is handled.
### 2. Skip blocking cleanup only for a full Windows session end
`WM_DESTROY` branches on `g_system_session_ending`:
- **User-initiated close or Restart Manager `ENDSESSION_CLOSEAPP`:**
unchanged full cleanup (`Shell_NotifyIcon(NIM_DELETE)`,
`close_settings_window()`, and `QuickAccessHost::stop()`).
- **Full OS shutdown, sign-out, or restart:** posts `WM_QUIT` without
waiting on child processes the OS is already reaping in parallel.
### Scope and follow-up
This PR intentionally fixes the highest-volume contributor: the
always-on runner. Native module processes with their own windows/message
loops require module-specific review before adopting the pattern; that
inventory and rollout is tracked in #49539.
### Why not centralize handling inside `run_message_loop`?
`WM_QUERYENDSESSION` / `WM_ENDSESSION` invoke the WndProc directly
during `GetMessage`; they do not appear as a `MSG` returned to the loop.
Handling must therefore live in, or be called from, each relevant
WndProc.
## Tests
8 focused tests in `src/common/UnitTests-CommonUtils/Window.Tests.cpp`:
| Test | Guards |
|---|---|
| `HandleStatelessSessionEndMessage_QueryEndSession_AllowsShutdown` |
`WM_QUERYENDSESSION` returns `TRUE`. |
| `HandleStatelessSessionEndMessage_EndSessionCancelled_DoesNotTearDown`
| `WM_ENDSESSION(FALSE)` does not destroy the window. |
|
`HandleStatelessSessionEndMessage_EndSessionConfirmed_TearsDownAndExitsLoop`
| `WM_ENDSESSION(TRUE)` destroys the window and exits before the longer
timer fallback. |
| `HandleStatelessSessionEndMessage_UnrelatedMessage_NotHandled` |
Unrelated messages fall through untouched. |
|
`HandleStatelessSessionEndMessage_EndSessionConfirmed_SignalsSystemSessionEnding`
| A full session end enables the no-wait teardown path. |
|
`HandleStatelessSessionEndMessage_CloseApp_DoesNotSignalSystemSessionEnding`
| Restart Manager closes the window while retaining normal child
cleanup. |
|
`HandleStatelessSessionEndMessage_EndSessionCancelled_DoesNotSignalSystemSessionEnding`
| Cancelled shutdown does not flag teardown. |
|
`HandleStatelessSessionEndMessage_QueryEndSession_DoesNotSignalSystemSessionEnding`
| The query phase does not flag teardown. |
**Build:** `runner.vcxproj` and `UnitTests-CommonUtils.vcxproj` build
clean (`x64|Release`). The 8 focused tests pass.
## Manual validation
1. Build PowerToys and start the runner.
2. Initiate a sign-off (`logoff`) or restart.
3. Confirm Event Viewer (`Windows Logs → Application`) shows no
`Application Hang` event for `PowerToys.exe`.
4. Right-click tray → Exit: confirm Settings.exe and the Quick Access
host shut down gracefully and no ghost tray icon remains.
(#48378 additionally captured real logoff/restart runs showing
`WM_ENDSESSION → WM_DESTROY` completing in 1–8 ms with no hang
events—the same full-session path used here.)
## Quality checklist
- [x] Linked work item: AB#55588441
- [x] Module follow-up: #49539
- [x] Cross-references #41260; supersedes #48378
- [x] Unit tests (8 in `Window.Tests.cpp`)
- [x] No new binaries
- [x] Localization: no end-user strings changed
- [x] Shared helper documents its stateless contract
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8d70b986-081a-43dd-bbfd-7e6351baef7a
2026-07-28 19:58:00 -07:00
|
|
|
// When the full Windows session is ending, the OS reaps the Quick Access
|
|
|
|
|
// host process in parallel, so its stop timeout is pure dead time against
|
|
|
|
|
// the quiesce budget. User exits and Restart Manager ENDSESSION_CLOSEAPP
|
|
|
|
|
// requests retain the full graceful cleanup.
|
|
|
|
|
if (!is_system_session_ending())
|
|
|
|
|
{
|
|
|
|
|
QuickAccessHost::stop();
|
|
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
return result;
|
2019-09-04 18:26:26 +02:00
|
|
|
}
|
2019-12-16 18:36:52 +01:00
|
|
|
|
2020-02-25 23:04:19 +03:00
|
|
|
// If the PT runner is launched as part of some action and manually by a user, e.g. being activated as a COM server
|
|
|
|
|
// for background toast notification handling, we should execute corresponding code flow instead of the main code flow.
|
|
|
|
|
enum class SpecialMode
|
|
|
|
|
{
|
|
|
|
|
None,
|
2020-03-24 17:17:25 +03:00
|
|
|
Win32ToastNotificationCOMServer,
|
2020-04-21 10:30:12 +03:00
|
|
|
ToastNotificationHandler,
|
|
|
|
|
ReportSuccessfulUpdate
|
2020-02-25 23:04:19 +03:00
|
|
|
};
|
|
|
|
|
|
2020-03-24 17:17:25 +03:00
|
|
|
SpecialMode should_run_in_special_mode(const int n_cmd_args, LPWSTR* cmd_arg_list)
|
2020-02-25 23:04:19 +03:00
|
|
|
{
|
2020-03-24 17:17:25 +03:00
|
|
|
for (size_t i = 1; i < n_cmd_args; ++i)
|
2020-02-25 23:04:19 +03:00
|
|
|
{
|
2020-03-24 17:17:25 +03:00
|
|
|
if (!wcscmp(notifications::TOAST_ACTIVATED_LAUNCH_ARG, cmd_arg_list[i]))
|
|
|
|
|
{
|
2020-02-25 23:04:19 +03:00
|
|
|
return SpecialMode::Win32ToastNotificationCOMServer;
|
2020-03-24 17:17:25 +03:00
|
|
|
}
|
|
|
|
|
else if (n_cmd_args == 2 && !wcsncmp(PT_URI_PROTOCOL_SCHEME, cmd_arg_list[i], wcslen(PT_URI_PROTOCOL_SCHEME)))
|
|
|
|
|
{
|
|
|
|
|
return SpecialMode::ToastNotificationHandler;
|
|
|
|
|
}
|
2021-05-21 13:32:34 +03:00
|
|
|
else if (n_cmd_args == 2 && !wcscmp(cmdArg::UPDATE_REPORT_SUCCESS, cmd_arg_list[i]))
|
2020-04-21 10:30:12 +03:00
|
|
|
{
|
|
|
|
|
return SpecialMode::ReportSuccessfulUpdate;
|
|
|
|
|
}
|
2020-02-25 23:04:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SpecialMode::None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int win32_toast_notification_COM_server_mode()
|
|
|
|
|
{
|
|
|
|
|
notifications::run_desktop_app_activator_loop();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 17:17:25 +03:00
|
|
|
enum class toast_notification_handler_result
|
|
|
|
|
{
|
|
|
|
|
exit_success,
|
|
|
|
|
exit_error
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
toast_notification_handler_result toast_notification_handler(const std::wstring_view param)
|
|
|
|
|
{
|
2020-06-18 13:43:09 +03:00
|
|
|
const std::wstring_view cant_drag_elevated_disable = L"cant_drag_elevated_disable/";
|
2020-10-20 01:27:24 +03:00
|
|
|
const std::wstring_view couldnt_toggle_powerpreview_modules_disable = L"couldnt_toggle_powerpreview_modules_disable/";
|
|
|
|
|
const std::wstring_view open_settings = L"open_settings/";
|
2024-10-28 15:10:18 +03:00
|
|
|
const std::wstring_view open_overview = L"open_overview/";
|
2020-10-20 01:27:24 +03:00
|
|
|
const std::wstring_view update_now = L"update_now/";
|
2020-06-18 13:43:09 +03:00
|
|
|
|
|
|
|
|
if (param == cant_drag_elevated_disable)
|
2020-03-24 17:17:25 +03:00
|
|
|
{
|
2023-12-28 13:33:04 +03:00
|
|
|
return notifications::disable_toast(notifications::ElevatedDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error;
|
2020-03-24 17:17:25 +03:00
|
|
|
}
|
2020-06-18 13:43:09 +03:00
|
|
|
else if (param.starts_with(update_now))
|
2020-04-21 10:30:12 +03:00
|
|
|
{
|
2021-05-21 13:32:34 +03:00
|
|
|
std::wstring args{ cmdArg::UPDATE_NOW_LAUNCH_STAGE1 };
|
2021-06-14 12:55:59 +03:00
|
|
|
LaunchPowerToysUpdate(args.c_str());
|
2020-04-21 10:30:12 +03:00
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
|
}
|
2020-10-20 01:27:24 +03:00
|
|
|
else if (param == couldnt_toggle_powerpreview_modules_disable)
|
|
|
|
|
{
|
|
|
|
|
return notifications::disable_toast(notifications::PreviewModulesDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error;
|
|
|
|
|
}
|
|
|
|
|
else if (param == open_settings)
|
|
|
|
|
{
|
2021-09-29 12:54:05 +02:00
|
|
|
open_menu_from_another_instance(std::nullopt);
|
2020-10-20 01:27:24 +03:00
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
|
}
|
2024-10-28 15:10:18 +03:00
|
|
|
else if (param == open_overview)
|
|
|
|
|
{
|
|
|
|
|
open_menu_from_another_instance("Overview");
|
|
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
|
}
|
2020-03-24 17:17:25 +03:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return toast_notification_handler_result::exit_error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-09 14:41:14 +00:00
|
|
|
int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR lpCmdLine, int /*nCmdShow*/)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2024-10-24 22:04:32 +02:00
|
|
|
Shared::Trace::ETWTrace trace{};
|
|
|
|
|
trace.UpdateState(true);
|
|
|
|
|
|
2021-06-29 13:06:12 +03:00
|
|
|
Gdiplus::GdiplusStartupInput gpStartupInput;
|
|
|
|
|
ULONG_PTR gpToken;
|
|
|
|
|
GdiplusStartup(&gpToken, &gpStartupInput, NULL);
|
|
|
|
|
|
2020-02-25 23:04:19 +03:00
|
|
|
winrt::init_apartment();
|
2025-09-26 13:03:00 +08:00
|
|
|
|
2020-08-05 19:06:50 +03:00
|
|
|
const wchar_t* securityDescriptor =
|
|
|
|
|
L"O:BA" // Owner: Builtin (local) administrator
|
|
|
|
|
L"G:BA" // Group: Builtin (local) administrator
|
|
|
|
|
L"D:"
|
|
|
|
|
L"(A;;0x7;;;PS)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Personal self
|
|
|
|
|
L"(A;;0x7;;;IU)" // Access allowed on COM_RIGHTS_EXECUTE for Interactive Users
|
|
|
|
|
L"(A;;0x3;;;SY)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Local system
|
|
|
|
|
L"(A;;0x7;;;BA)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Builtin (local) administrator
|
|
|
|
|
L"(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability
|
|
|
|
|
L"S:"
|
|
|
|
|
L"(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
|
|
|
|
|
initializeCOMSecurity(securityDescriptor);
|
2020-02-25 23:04:19 +03:00
|
|
|
|
2020-03-24 17:17:25 +03:00
|
|
|
int n_cmd_args = 0;
|
|
|
|
|
LPWSTR* cmd_arg_list = CommandLineToArgvW(GetCommandLineW(), &n_cmd_args);
|
|
|
|
|
switch (should_run_in_special_mode(n_cmd_args, cmd_arg_list))
|
2020-02-25 23:04:19 +03:00
|
|
|
{
|
|
|
|
|
case SpecialMode::Win32ToastNotificationCOMServer:
|
|
|
|
|
return win32_toast_notification_COM_server_mode();
|
2020-03-24 17:17:25 +03:00
|
|
|
case SpecialMode::ToastNotificationHandler:
|
|
|
|
|
switch (toast_notification_handler(cmd_arg_list[1] + wcslen(PT_URI_PROTOCOL_SCHEME)))
|
|
|
|
|
{
|
|
|
|
|
case toast_notification_handler_result::exit_error:
|
|
|
|
|
return 1;
|
|
|
|
|
case toast_notification_handler_result::exit_success:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2022-12-18 15:58:30 +00:00
|
|
|
[[fallthrough]];
|
2020-04-21 10:30:12 +03:00
|
|
|
case SpecialMode::ReportSuccessfulUpdate:
|
2020-10-20 14:00:06 +03:00
|
|
|
{
|
2020-12-17 19:34:55 +03:00
|
|
|
notifications::remove_toasts_by_tag(notifications::UPDATING_PROCESS_TOAST_TAG);
|
|
|
|
|
notifications::remove_all_scheduled_toasts();
|
2020-10-22 19:02:59 +03:00
|
|
|
notifications::show_toast(GET_RESOURCE_STRING(IDS_PT_UPDATE_MESSAGE_BOX_TEXT),
|
2020-10-20 14:00:06 +03:00
|
|
|
L"PowerToys",
|
|
|
|
|
notifications::toast_params{ notifications::UPDATING_PROCESS_TOAST_TAG });
|
2020-04-21 10:30:12 +03:00
|
|
|
break;
|
2020-10-20 14:00:06 +03:00
|
|
|
}
|
2020-04-21 10:30:12 +03:00
|
|
|
|
2020-02-25 23:04:19 +03:00
|
|
|
case SpecialMode::None:
|
|
|
|
|
// continue as usual
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 20:56:37 +03:00
|
|
|
std::filesystem::path logFilePath(PTSettingsHelper::get_root_save_folder_location());
|
|
|
|
|
logFilePath.append(LogSettings::runnerLogPath);
|
|
|
|
|
Logger::init(LogSettings::runnerLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
|
|
|
|
|
2021-09-29 12:54:05 +02:00
|
|
|
const std::string cmdLine{ lpCmdLine };
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info("Running powertoys with cmd args: {}", cmdLine);
|
|
|
|
|
|
2021-09-29 12:54:05 +02:00
|
|
|
auto open_settings_it = cmdLine.find("--open-settings");
|
|
|
|
|
const bool open_settings = open_settings_it != std::string::npos;
|
|
|
|
|
// Check if opening specific settings window
|
|
|
|
|
open_settings_it = cmdLine.find("--open-settings=");
|
|
|
|
|
std::string settings_window;
|
|
|
|
|
if (open_settings_it != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
std::string rest_of_cmd_line{ cmdLine, open_settings_it + std::string{ "--open-settings=" }.size() };
|
|
|
|
|
std::istringstream iss(rest_of_cmd_line);
|
|
|
|
|
iss >> settings_window;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 14:20:11 -07:00
|
|
|
// Check if another instance is already running.
|
|
|
|
|
wil::unique_mutex_nothrow msi_mutex = create_msi_mutex();
|
|
|
|
|
if (!msi_mutex)
|
2020-02-18 18:11:01 +03:00
|
|
|
{
|
2021-09-29 12:54:05 +02:00
|
|
|
open_menu_from_another_instance(settings_window);
|
2021-06-03 14:20:11 -07:00
|
|
|
return 0;
|
2020-02-18 18:11:01 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 20:56:37 +03:00
|
|
|
bool openOobe = false;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
openOobe = !PTSettingsHelper::get_oobe_opened_state();
|
|
|
|
|
}
|
|
|
|
|
catch (const std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
Logger::error("Failed to get or save OOBE state with an exception: {}", e.what());
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 11:02:08 +00:00
|
|
|
bool openScoobe = false;
|
2024-01-18 16:18:17 +01:00
|
|
|
bool showRestartNotificationAfterUpdate = false;
|
2022-02-22 11:02:08 +00:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
std::wstring last_version_run = PTSettingsHelper::get_last_version_run();
|
2023-07-28 17:23:54 +02:00
|
|
|
const auto product_version = get_product_version();
|
|
|
|
|
openScoobe = product_version != last_version_run;
|
2024-01-18 16:18:17 +01:00
|
|
|
showRestartNotificationAfterUpdate = openScoobe;
|
2023-07-28 17:23:54 +02:00
|
|
|
Logger::info(L"Scoobe: product_version={} last_version_run={}", product_version, last_version_run);
|
2022-02-22 11:02:08 +00:00
|
|
|
}
|
|
|
|
|
catch (const std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
Logger::error("Failed to get last version with an exception: {}", e.what());
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
int result = 0;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// Singletons initialization order needs to be preserved, first events and
|
|
|
|
|
// then modules to guarantee the reverse destruction order.
|
|
|
|
|
modules();
|
2019-12-16 18:36:52 +01:00
|
|
|
|
2022-08-23 22:32:45 +02:00
|
|
|
std::thread{ [] {
|
2023-08-14 10:55:12 +02:00
|
|
|
auto state = UpdateState::read();
|
|
|
|
|
if (state.state == UpdateState::upToDate)
|
|
|
|
|
{
|
|
|
|
|
updating::cleanup_updates();
|
|
|
|
|
}
|
2022-08-23 22:32:45 +02:00
|
|
|
} }.detach();
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
auto general_settings = load_general_settings();
|
2020-06-26 14:46:47 -07:00
|
|
|
|
|
|
|
|
// Apply the general settings but don't save it as the modules() variable has not been loaded yet
|
|
|
|
|
apply_general_settings(general_settings, false);
|
2020-03-24 17:17:25 +03:00
|
|
|
const bool elevated = is_process_elevated();
|
2022-02-08 11:18:12 +01:00
|
|
|
const bool with_dont_elevate_arg = cmdLine.find("--dont-elevate") != std::string::npos;
|
|
|
|
|
const bool run_elevated_setting = general_settings.GetNamedBoolean(L"run_elevated", false);
|
2023-08-10 12:59:36 +02:00
|
|
|
const bool with_restartedElevated_arg = cmdLine.find("--restartedElevated") != std::string::npos;
|
2022-02-02 11:23:40 +01:00
|
|
|
|
2024-01-18 16:18:17 +01:00
|
|
|
// Update scoobe behavior based on setting and gpo
|
|
|
|
|
bool scoobeSettingDisabled = general_settings.GetNamedBoolean(L"show_whats_new_after_updates", true) == false;
|
|
|
|
|
bool scoobeDisabledByGpo = powertoys_gpo::getDisableShowWhatsNewAfterUpdatesValue() == powertoys_gpo::gpo_rule_configured_enabled;
|
|
|
|
|
if (openScoobe && (scoobeSettingDisabled || scoobeDisabledByGpo))
|
|
|
|
|
{
|
|
|
|
|
// Scoobe should show after an update, but is disabled by policy or setting
|
|
|
|
|
Logger::info(L"Scoobe: Showing scoobe after updates is disabled by setting or by GPO.");
|
|
|
|
|
openScoobe = false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
bool dataDiagnosticsDisabledByGpo = powertoys_gpo::getAllowDataDiagnosticsValue() == powertoys_gpo::gpo_rule_configured_disabled;
|
|
|
|
|
if (dataDiagnosticsDisabledByGpo)
|
|
|
|
|
{
|
|
|
|
|
Logger::info(L"Data diagnostics: Data diagnostics is disabled by GPO.");
|
|
|
|
|
PTSettingsHelper::save_data_diagnostics(false);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 11:18:12 +01:00
|
|
|
if (elevated && with_dont_elevate_arg && !run_elevated_setting)
|
|
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info("Scheduling restart as non elevated");
|
2022-02-02 11:23:40 +01:00
|
|
|
schedule_restart_as_non_elevated();
|
|
|
|
|
result = 0;
|
|
|
|
|
}
|
2023-08-10 12:59:36 +02:00
|
|
|
else if (elevated || !run_elevated_setting || with_dont_elevate_arg || (!elevated && with_restartedElevated_arg))
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2023-08-10 12:59:36 +02:00
|
|
|
// The condition (!elevated && with_restartedElevated_arg) solves issue #19307. Restart elevated loop detected, running non-elevated
|
|
|
|
|
if (!elevated && with_restartedElevated_arg)
|
|
|
|
|
{
|
|
|
|
|
Logger::info("Restart as elevated failed. Running non-elevated.");
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-18 16:18:17 +01:00
|
|
|
result = runner(elevated, open_settings, settings_window, openOobe, openScoobe, showRestartNotificationAfterUpdate);
|
2022-02-02 10:54:03 +01:00
|
|
|
|
2022-10-13 03:41:21 -04:00
|
|
|
if (result == 0)
|
|
|
|
|
{
|
|
|
|
|
// Save settings on closing, if closed 'normal'
|
2022-11-22 18:20:32 +00:00
|
|
|
PTSettingsHelper::save_general_settings(get_general_settings().to_json());
|
2022-10-13 03:41:21 -04:00
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-02-22 12:50:20 +01:00
|
|
|
Logger::info("Scheduling restart as elevated");
|
2021-09-29 12:54:05 +02:00
|
|
|
schedule_restart_as_elevated(open_settings);
|
2019-12-26 17:26:11 +01:00
|
|
|
result = 0;
|
|
|
|
|
}
|
2019-12-16 18:36:52 +01:00
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
catch (std::runtime_error& err)
|
|
|
|
|
{
|
|
|
|
|
std::string err_what = err.what();
|
2020-01-09 18:17:42 +01:00
|
|
|
MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR);
|
2019-12-26 17:26:11 +01:00
|
|
|
result = -1;
|
2019-12-16 18:36:52 +01:00
|
|
|
}
|
2020-02-21 11:12:04 +01:00
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
trace.Flush();
|
|
|
|
|
trace.UpdateState(false);
|
|
|
|
|
|
2020-02-21 11:12:04 +01:00
|
|
|
// We need to release the mutexes to be able to restart the application
|
|
|
|
|
if (msi_mutex)
|
|
|
|
|
{
|
|
|
|
|
msi_mutex.reset(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
if (is_restart_scheduled())
|
|
|
|
|
{
|
2024-10-24 22:04:32 +02:00
|
|
|
modules().clear();
|
2022-02-08 11:18:12 +01:00
|
|
|
if (!restart_if_scheduled())
|
|
|
|
|
{
|
2022-04-21 14:59:29 +01:00
|
|
|
// If it's not possible to restart non-elevated due to some condition in the user's configuration, user should start PowerToys manually.
|
|
|
|
|
Logger::warn("Scheduled restart failed. Couldn't restart non-elevated. PowerToys exits here because retrying it would just mean failing in a loop.");
|
2019-12-26 17:26:11 +01:00
|
|
|
}
|
2019-12-16 18:36:52 +01:00
|
|
|
}
|
2019-12-26 17:26:11 +01:00
|
|
|
stop_tray_icon();
|
2025-09-26 13:03:00 +08:00
|
|
|
|
2019-12-26 17:26:11 +01:00
|
|
|
return result;
|
2019-12-16 18:36:52 +01:00
|
|
|
}
|