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>
|
|
|
|
|
#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>
|
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>
|
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"
|
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>
|
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
|
|
|
}
|
|
|
|
|
|
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);
|
2021-09-29 12:54:05 +02:00
|
|
|
LPARAM msg = static_cast<LPARAM>(ESettingsWindowNames::Overview);
|
|
|
|
|
if (settings_window.has_value())
|
|
|
|
|
{
|
|
|
|
|
msg = static_cast<LPARAM>(ESettingsWindowNames_from_string(settings_window.value()));
|
|
|
|
|
}
|
|
|
|
|
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);
|
2020-02-21 11:12:04 +01:00
|
|
|
}
|
|
|
|
|
|
2021-03-25 12:26:11 +03:00
|
|
|
void debug_verify_launcher_assets()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
|
const fs::path powertoysRoot = get_module_folderpath();
|
|
|
|
|
constexpr std::array<std::string_view, 4> assetsToCheck = { "modules\\launcher\\Images\\app.dark.png",
|
|
|
|
|
"modules\\launcher\\Images\\app.light.png",
|
|
|
|
|
"modules\\launcher\\Images\\app_error.dark.png",
|
|
|
|
|
"modules\\launcher\\Images\\app_error.light.png" };
|
|
|
|
|
for (const auto asset : assetsToCheck)
|
|
|
|
|
{
|
|
|
|
|
const auto assetPath = powertoysRoot / asset;
|
|
|
|
|
if (!fs::is_regular_file(assetPath))
|
|
|
|
|
{
|
2021-05-21 13:32:34 +03:00
|
|
|
Logger::error("{} couldn't be found.", assetPath.string());
|
2021-03-25 12:26:11 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 11:02:08 +00:00
|
|
|
int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2020-11-30 16:16:49 +02:00
|
|
|
Logger::info("Runner is starting. Elevated={}", isProcessElevated);
|
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();
|
|
|
|
|
start_tray_icon();
|
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
|
|
|
|
|
{
|
2021-03-25 12:26:11 +03:00
|
|
|
debug_verify_launcher_assets();
|
|
|
|
|
|
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();
|
|
|
|
|
|
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();
|
2020-06-22 13:01:33 +03:00
|
|
|
// Load Powertoys DLLs
|
|
|
|
|
|
2021-06-29 13:06:12 +03:00
|
|
|
std::vector<std::wstring_view> knownModules = {
|
2021-12-10 10:50:46 +01:00
|
|
|
L"modules/FancyZones/PowerToys.FancyZonesModuleInterface.dll",
|
|
|
|
|
L"modules/FileExplorerPreview/PowerToys.powerpreview.dll",
|
|
|
|
|
L"modules/ImageResizer/PowerToys.ImageResizerExt.dll",
|
|
|
|
|
L"modules/KeyboardManager/PowerToys.KeyboardManager.dll",
|
|
|
|
|
L"modules/Launcher/PowerToys.Launcher.dll",
|
|
|
|
|
L"modules/PowerRename/PowerToys.PowerRenameExt.dll",
|
|
|
|
|
L"modules/ShortcutGuide/ShortcutGuideModuleInterface/PowerToys.ShortcutGuideModuleInterface.dll",
|
|
|
|
|
L"modules/ColorPicker/PowerToys.ColorPicker.dll",
|
|
|
|
|
L"modules/Awake/PowerToys.AwakeModuleInterface.dll",
|
2022-10-13 03:41:21 -04:00
|
|
|
L"modules/MouseUtils/PowerToys.FindMyMouse.dll",
|
2021-12-29 20:33:20 +03:00
|
|
|
L"modules/MouseUtils/PowerToys.MouseHighlighter.dll",
|
2023-02-24 13:30:30 +00:00
|
|
|
L"modules/MouseUtils/PowerToys.MouseJump.dll",
|
2021-12-29 20:33:20 +03:00
|
|
|
L"modules/AlwaysOnTop/PowerToys.AlwaysOnTopModuleInterface.dll",
|
2022-01-26 14:01:24 +00:00
|
|
|
L"modules/MouseUtils/PowerToys.MousePointerCrosshairs.dll",
|
2022-08-26 18:01:50 +02:00
|
|
|
L"modules/PowerAccent/PowerToys.PowerAccentModuleInterface.dll",
|
2022-08-25 05:25:52 -05:00
|
|
|
L"modules/PowerOCR/PowerToys.PowerOCRModuleInterface.dll",
|
2023-02-23 06:59:49 -08:00
|
|
|
L"modules/PastePlain/PowerToys.PastePlainModuleInterface.dll",
|
[New PowerToy] File Locksmith (#20930)
* Imported offline solution
* Make solution compile
* Add Windows sample, doesn't work?
* Added new project to implement the dll
* Remove unneeded header
* Implemented IUnknown part of ExplorerCommand
* Implemented IExplorerCommand methods
* Implemented ClassFactory
* Implemented DLL register/unregister
* Implemented other DLL exports, not working?
* Implemented IShellExtInit inferface
* Implemented IContextMenu, it works!
* Implement command data fetching
* Make sample project compile on VS 2022
* Add plan
* Implement Lib as separate project
* Implemented IPC, not tested
* Console UI project skeleton
* Implemented basic console UI
* Implemented piping, there are bugs
* Prototype works
* Remove old project
* Added GUI project skeleton
* Mitigate issue with WinUI3
* Added a control for displaying results
* Add button
* Implement core functions in lib project
* Call new library function from console main
* Implement showing results
* Improve UI
* Implemented subdirectory search
* Remove useless code
* Set window size
* UI adjustments
* Implement killing process
* Rename variable
* Add lib project to main solution
* Add Ext and GUI projects to solution
* Tweak packages for GUI project
* Add a settings page
* Add a few resource strings
* Add one more resources string
* VS keeps trying to correct this
* Add references to File Locksmith in /,github
* Implement some parts of FileLocksmithModule
* Change output directory
* Change target name and add to runner
* Add logger
* Started implementing settings backend
* Fix log folder
* Settings work
* Add some basic tracing
* Attempt at adding resources
* Remove junk files
* Added missing defines
* Replaced some constants with resources
Something's not working
* Move resources to the Ext project
* Remove experiment
* Add binaries for signing
* Improve tracing
* Remove old Settings calls
* Show something when there are no results
* Change window title
* Move computation to another thread, improve UX
* Increase font size for default text
* Remove entries for killed processes
* Show user name
* Remove nonrecursive implementation
* Implement back end for getting file names
* Show list of files, UI tweaks
* Remove useless includes
* Implement back end for getting full process path
* Dark title bar on dark themes
* Using Expander, other UI adjustments
* Show "No results" after killing all processes
* Show progress ring
* Update configuration mapping
* Revert "Update configuration mapping"
This reverts commit d8e13206f3c7de3c6dbf880299bfff3bf9f27a37.
* Fixed solution configuration, ARM64 should build
* Backend for refreshing
* Variable window size
* Add refresh button
* New WinUI3 C# project for FL
* Started porting functionality
* Add Interop project
* Move IPC to Ext project
* Ported native functions to Interop
* Ported finding processes
* Ported most of Main Window functionality
* Display paths of files
* Implement killing processes
* Use resource string for "End Task"
* Remove entries for terminated processes
* Show User name
* Set default window size
* Make the new UI the default
* Reading paths from stdin, completed port to C#
* Fix small bug
* Moving to MVVM
* Adding Labs
* Merge branch 'ivan/file-locksmith' of https://github.com/microsoft/PowerToys into ivan/file-locksmith
Removing one parent commit for cleaner history
Co-Authored-By: Niels Laute <niels.laute@live.nl>
* Reintroducing features
* Moving UI strings to resources file
* Restored functionality
* Add missing dlls
* Add FIle Locksmith to publish.cmd
* Rebase fixes
* Try updating nuget.config
* Fix copy-paste blunder
* Add File Locksmith UI for publishing
* Add .pubxml file in FileLocksmith
* Change build output folder
* Fix installer build issues
Remove old projects from solution so MSBuild doesn't build them.
Downgrade target framework to what most other projects are using.
Fix publishing profile and project runtimes.
Remove unused CsWinRT references.
* [CI] Add clear to nuget packages
* Fix module reference counting
* Fix nuget for release CI
* Fix version and signing
* Fix path for resources
* Fix incorrect results when running 2 instances
* Fix default nuget source
* Windows 10 icon and fallback for UI
* Code clean-up and spaces instead of tabs
* Add gif showcasing FL
* Add screenshot of File Locksmith for Settings
* Add new files to the installer
* Add OOBE page
* Showing selected paths in the header
* Tweak path list
* Added new, wider gif
* Add GPO
* Add some logs
* [CI]Get CommunityToolkit.Labs from BigPark feed
* [CI]Use azure package feed for Nuget in release
* [CI]Another try for the labs source
* Revert changes to feed
* Use RestoreAdditionalProjectSources
* Add tooltip to file list
* Change tooltip to not trim the lines
* Add Tips and tricks section mentioning elevated
* Add some more logs messages.
* Grammar fix
* Add to bug report tool
* Fix UI virtualization not working
* Disable virtualization to avoid crashes
* Get better virtualization
* Add dialog instead of tooltip to show list of items
* No results refresh icon is now a button too
* Use managed methods for handling processes
* Remove registry code from Ext.
* Support drives too
Co-authored-by: Niels Laute <niels.laute@live.nl>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2022-10-28 15:51:21 +02:00
|
|
|
L"modules/FileLocksmith/PowerToys.FileLocksmithExt.dll",
|
2022-08-27 02:17:20 +03:00
|
|
|
L"modules/MeasureTool/PowerToys.MeasureToolModuleInterface.dll",
|
2022-10-13 13:05:43 +02:00
|
|
|
L"modules/Hosts/PowerToys.HostsModuleInterface.dll",
|
2019-12-26 17:26:11 +01:00
|
|
|
};
|
2021-12-10 10:50:46 +01:00
|
|
|
const auto VCM_PATH = L"modules/VideoConference/PowerToys.VideoConferenceModule.dll";
|
2021-10-07 16:48:45 +03:00
|
|
|
if (const auto mf = LoadLibraryA("mf.dll"))
|
|
|
|
|
{
|
|
|
|
|
FreeLibrary(mf);
|
|
|
|
|
knownModules.emplace_back(VCM_PATH);
|
|
|
|
|
}
|
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;
|
|
|
|
|
MessageBoxW(NULL,
|
|
|
|
|
errorMessage.c_str(),
|
|
|
|
|
L"PowerToys",
|
|
|
|
|
MB_OK | MB_ICONERROR);
|
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);
|
|
|
|
|
}
|
2023-01-31 00:00:11 +01:00
|
|
|
open_settings_window(window, false);
|
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();
|
|
|
|
|
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/";
|
|
|
|
|
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
|
|
|
{
|
2020-10-20 01:27:24 +03:00
|
|
|
return notifications::disable_toast(notifications::CantDragElevatedDontShowAgainRegistryPath) ? 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;
|
|
|
|
|
}
|
2020-03-24 17:17:25 +03:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return toast_notification_handler_result::exit_error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-23 22:32:45 +02:00
|
|
|
void cleanup_updates()
|
|
|
|
|
{
|
|
|
|
|
auto state = UpdateState::read();
|
|
|
|
|
if (state.state != UpdateState::upToDate)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-24 12:04:23 +02:00
|
|
|
auto update_dir = updating::get_pending_updates_path();
|
|
|
|
|
if (std::filesystem::exists(update_dir))
|
2022-08-23 22:32:45 +02:00
|
|
|
{
|
2022-08-24 12:04:23 +02:00
|
|
|
// Msi and exe files
|
|
|
|
|
for (const auto& entry : std::filesystem::directory_iterator(update_dir))
|
2022-08-23 22:32:45 +02:00
|
|
|
{
|
2022-08-24 12:04:23 +02:00
|
|
|
auto entryPath = entry.path().wstring();
|
|
|
|
|
std::transform(entryPath.begin(), entryPath.end(), entryPath.begin(), ::towlower);
|
|
|
|
|
|
|
|
|
|
if (entryPath.ends_with(L".msi") || entryPath.ends_with(L".exe"))
|
2022-08-23 22:32:45 +02:00
|
|
|
{
|
2022-08-24 12:04:23 +02:00
|
|
|
std::error_code err;
|
|
|
|
|
std::filesystem::remove(entry, err);
|
|
|
|
|
if (err.value())
|
|
|
|
|
{
|
|
|
|
|
Logger::warn("Failed to delete installer file {}. {}", entry.path().string(), err.message());
|
|
|
|
|
}
|
2022-08-23 22:32:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-13 03:41:21 -04:00
|
|
|
|
2022-08-23 22:32:45 +02:00
|
|
|
// Log files
|
|
|
|
|
auto rootPath{ PTSettingsHelper::get_root_save_folder_location() };
|
|
|
|
|
auto currentVersion = left_trim<wchar_t>(get_product_version(), L"v");
|
2022-08-24 12:04:23 +02:00
|
|
|
if (std::filesystem::exists(rootPath))
|
2022-08-23 22:32:45 +02:00
|
|
|
{
|
2022-08-24 12:04:23 +02:00
|
|
|
for (const auto& entry : std::filesystem::directory_iterator(rootPath))
|
2022-08-23 22:32:45 +02:00
|
|
|
{
|
2022-08-24 12:04:23 +02:00
|
|
|
auto entryPath = entry.path().wstring();
|
|
|
|
|
std::transform(entryPath.begin(), entryPath.end(), entryPath.begin(), ::towlower);
|
|
|
|
|
if (entry.is_regular_file() && entryPath.ends_with(L".log") && entryPath.find(currentVersion) == std::string::npos)
|
2022-08-23 22:32:45 +02:00
|
|
|
{
|
2022-08-24 12:04:23 +02:00
|
|
|
std::error_code err;
|
|
|
|
|
std::filesystem::remove(entry, err);
|
|
|
|
|
if (err.value())
|
|
|
|
|
{
|
|
|
|
|
Logger::warn("Failed to delete log file {}. {}", entry.path().string(), err.message());
|
|
|
|
|
}
|
2022-08-23 22:32:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
{
|
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();
|
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;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
std::wstring last_version_run = PTSettingsHelper::get_last_version_run();
|
|
|
|
|
openScoobe = last_version_run != get_product_version();
|
|
|
|
|
}
|
|
|
|
|
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{ [] {
|
|
|
|
|
cleanup_updates();
|
|
|
|
|
} }.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);
|
2022-02-02 11:23:40 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
2022-02-08 11:18:12 +01:00
|
|
|
else if (elevated || !run_elevated_setting || with_dont_elevate_arg)
|
2019-12-26 17:26:11 +01:00
|
|
|
{
|
2022-02-22 11:02:08 +00:00
|
|
|
result = runner(elevated, open_settings, settings_window, openOobe, openScoobe);
|
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
|
|
|
|
|
|
|
|
// 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())
|
|
|
|
|
{
|
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();
|
|
|
|
|
return result;
|
2019-12-16 18:36:52 +01:00
|
|
|
}
|