2019-09-05 00:26:26 +08:00
|
|
|
#include "pch.h"
|
|
|
|
#include <ShellScalingApi.h>
|
|
|
|
#include <lmcons.h>
|
|
|
|
#include <filesystem>
|
|
|
|
#include "tray_icon.h"
|
|
|
|
#include "powertoy_module.h"
|
|
|
|
#include "trace.h"
|
|
|
|
#include "general_settings.h"
|
2019-12-17 01:36:52 +08:00
|
|
|
#include "restart_elevated.h"
|
2020-12-15 20:16:09 +08:00
|
|
|
#include "RestartManagement.h"
|
2020-09-10 21:57:16 +08:00
|
|
|
#include "Generated files/resource.h"
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-12-15 20:16:09 +08: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 16:34:34 +08:00
|
|
|
#include <common/updating/installer.h>
|
2020-10-20 06:27:24 +08:00
|
|
|
#include <common/updating/updating.h>
|
2020-12-15 20:16:09 +08:00
|
|
|
#include <common/utils/appMutex.h>
|
|
|
|
#include <common/utils/elevation.h>
|
|
|
|
#include <common/utils/processApi.h>
|
|
|
|
#include <common/utils/resources.h>
|
|
|
|
#include <common/winstore/winstore.h>
|
2020-02-20 22:04:56 +08:00
|
|
|
|
|
|
|
#include "update_state.h"
|
2020-04-21 15:30:12 +08:00
|
|
|
#include "update_utils.h"
|
|
|
|
#include "action_runner_utils.h"
|
2020-02-20 22:04:56 +08:00
|
|
|
|
|
|
|
#include <winrt/Windows.System.h>
|
2020-02-05 00:41:00 +08:00
|
|
|
|
2020-06-11 16:09:06 +08:00
|
|
|
#include <Psapi.h>
|
|
|
|
#include <RestartManager.h>
|
2020-09-21 18:44:16 +08:00
|
|
|
#include "centralized_kb_hook.h"
|
2020-06-11 16:09:06 +08:00
|
|
|
|
2019-09-05 00:26:26 +08:00
|
|
|
#if _DEBUG && _WIN64
|
|
|
|
#include "unhandled_exception_handler.h"
|
|
|
|
#endif
|
2020-12-15 20:16:09 +08:00
|
|
|
#include <common/SettingsAPI/settings_helpers.h>
|
2020-11-18 18:15:14 +08:00
|
|
|
#include <common/logger/logger.h>
|
2020-12-15 20:16:09 +08:00
|
|
|
#include <common/utils/winapi_error.h>
|
|
|
|
#include <common/version/version.h>
|
|
|
|
#include <common/utils/window.h>
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-10-23 00:02:59 +08:00
|
|
|
extern updating::notifications::strings Strings;
|
2020-02-18 23:11:01 +08:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2020-03-24 22:17:25 +08:00
|
|
|
const wchar_t PT_URI_PROTOCOL_SCHEME[] = L"powertoys://";
|
2020-10-23 00:02:59 +08: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 23:11:01 +08:00
|
|
|
}
|
|
|
|
|
2019-12-27 00:26:11 +08: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-23 00:02:59 +08:00
|
|
|
show_last_error_message(L"Change Directory to Executable Path", GetLastError(), L"PowerToys - runner");
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
|
|
|
|
2020-07-28 00:53:29 +08:00
|
|
|
inline wil::unique_mutex_nothrow create_msi_mutex()
|
2020-02-18 23:11:01 +08:00
|
|
|
{
|
2020-07-28 00:53:29 +08:00
|
|
|
return createAppMutex(POWERTOYS_MSI_MUTEX_NAME);
|
2020-02-18 23:11:01 +08:00
|
|
|
}
|
|
|
|
|
2020-07-28 00:53:29 +08:00
|
|
|
inline wil::unique_mutex_nothrow create_msix_mutex()
|
2020-02-21 18:12:04 +08:00
|
|
|
{
|
2020-07-28 00:53:29 +08:00
|
|
|
return createAppMutex(POWERTOYS_MSIX_MUTEX_NAME);
|
2020-02-21 18:12:04 +08:00
|
|
|
}
|
|
|
|
|
2020-04-07 18:17:18 +08:00
|
|
|
void open_menu_from_another_instance()
|
2020-02-21 18:12:04 +08:00
|
|
|
{
|
2020-07-28 00:53:29 +08:00
|
|
|
const HWND hwnd_main = FindWindowW(L"PToyTrayIconWindow", nullptr);
|
|
|
|
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, 0);
|
2020-02-21 18:12:04 +08:00
|
|
|
}
|
|
|
|
|
2020-02-12 18:03:40 +08:00
|
|
|
int runner(bool isProcessElevated)
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-11-30 22:16:49 +08: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());
|
|
|
|
|
|
|
|
Logger::info("Runner is starting. Elevated={}", isProcessElevated);
|
2019-12-27 00:26:11 +08:00
|
|
|
DPIAware::EnableDPIAwarenessForThisProcess();
|
|
|
|
|
|
|
|
#if _DEBUG && _WIN64
|
|
|
|
//Global error handlers to diagnose errors.
|
|
|
|
//We prefer this not not show any longer until there's a bug to diagnose.
|
|
|
|
//init_global_error_handlers();
|
|
|
|
#endif
|
|
|
|
Trace::RegisterProvider();
|
|
|
|
start_tray_icon();
|
2020-09-21 18:44:16 +08:00
|
|
|
CentralizedKeyboardHook::Start();
|
2020-02-18 23:11:01 +08:00
|
|
|
|
|
|
|
int result = -1;
|
2019-12-27 00:26:11 +08:00
|
|
|
try
|
|
|
|
{
|
2020-03-12 15:59:10 +08:00
|
|
|
std::thread{ [] {
|
2020-04-21 15:30:12 +08:00
|
|
|
github_update_worker();
|
2020-03-12 15:59:10 +08:00
|
|
|
} }.detach();
|
|
|
|
|
|
|
|
if (winstore::running_as_packaged())
|
|
|
|
{
|
|
|
|
std::thread{ [] {
|
|
|
|
start_msi_uninstallation_sequence();
|
|
|
|
} }.detach();
|
|
|
|
}
|
2020-04-04 00:51:28 +08:00
|
|
|
else
|
|
|
|
{
|
2020-04-21 15:30:12 +08:00
|
|
|
std::thread{ [] {
|
|
|
|
if (updating::uninstall_previous_msix_version_async().get())
|
2020-04-04 00:51:28 +08:00
|
|
|
{
|
2020-10-23 00:02:59 +08:00
|
|
|
notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L"PowerToys");
|
2020-04-04 00:51:28 +08:00
|
|
|
}
|
2020-04-21 15:30:12 +08:00
|
|
|
} }.detach();
|
2020-04-04 00:51:28 +08:00
|
|
|
}
|
2020-03-12 15:59:10 +08:00
|
|
|
|
2020-02-26 04:04:19 +08:00
|
|
|
notifications::register_background_toast_handler();
|
2020-02-18 23:11:01 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
chdir_current_executable();
|
2020-06-22 18:01:33 +08:00
|
|
|
// Load Powertoys DLLs
|
|
|
|
|
2020-07-19 03:27:36 +08:00
|
|
|
const std::array<std::wstring_view, 8> knownModules = {
|
2020-06-22 18:01:33 +08:00
|
|
|
L"modules/FancyZones/fancyzones.dll",
|
|
|
|
L"modules/FileExplorerPreview/powerpreview.dll",
|
|
|
|
L"modules/ImageResizer/ImageResizerExt.dll",
|
|
|
|
L"modules/KeyboardManager/KeyboardManager.dll",
|
|
|
|
L"modules/Launcher/Microsoft.Launcher.dll",
|
|
|
|
L"modules/PowerRename/PowerRenameExt.dll",
|
|
|
|
L"modules/ShortcutGuide/ShortcutGuide.dll",
|
2020-07-19 03:27:36 +08:00
|
|
|
L"modules/ColorPicker/ColorPicker.dll",
|
2019-12-27 00:26:11 +08:00
|
|
|
};
|
2020-05-08 23:23:18 +08:00
|
|
|
|
2020-07-28 00:53:29 +08:00
|
|
|
for (const auto& moduleSubdir : knownModules)
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-06-22 18:01:33 +08:00
|
|
|
try
|
|
|
|
{
|
2021-01-09 02:26:38 +08:00
|
|
|
auto pt_module = load_powertoy(moduleSubdir);
|
|
|
|
modules().emplace(pt_module->get_key(), std::move(pt_module));
|
2020-06-22 18:01:33 +08:00
|
|
|
}
|
|
|
|
catch (...)
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-10-23 00:02:59 +08:00
|
|
|
std::wstring errorMessage = POWER_TOYS_MODULE_LOAD_FAIL;
|
|
|
|
errorMessage += moduleSubdir;
|
|
|
|
MessageBoxW(NULL,
|
|
|
|
errorMessage.c_str(),
|
|
|
|
L"PowerToys",
|
|
|
|
MB_OK | MB_ICONERROR);
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Start initial powertoys
|
|
|
|
start_initial_powertoys();
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2020-02-12 18:03:40 +08:00
|
|
|
Trace::EventLaunch(get_product_version(), isProcessElevated);
|
2019-09-05 00:26:26 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
result = run_message_loop();
|
|
|
|
}
|
|
|
|
catch (std::runtime_error& err)
|
|
|
|
{
|
|
|
|
std::string err_what = err.what();
|
2020-01-10 01:17:42 +08: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-27 00:26:11 +08:00
|
|
|
result = -1;
|
|
|
|
}
|
|
|
|
Trace::UnregisterProvider();
|
|
|
|
return result;
|
2019-09-05 00:26:26 +08:00
|
|
|
}
|
2019-12-17 01:36:52 +08:00
|
|
|
|
2020-02-26 04:04:19 +08: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 22:17:25 +08:00
|
|
|
Win32ToastNotificationCOMServer,
|
2020-04-21 15:30:12 +08:00
|
|
|
ToastNotificationHandler,
|
|
|
|
ReportSuccessfulUpdate
|
2020-02-26 04:04:19 +08:00
|
|
|
};
|
|
|
|
|
2020-03-24 22:17:25 +08:00
|
|
|
SpecialMode should_run_in_special_mode(const int n_cmd_args, LPWSTR* cmd_arg_list)
|
2020-02-26 04:04:19 +08:00
|
|
|
{
|
2020-03-24 22:17:25 +08:00
|
|
|
for (size_t i = 1; i < n_cmd_args; ++i)
|
2020-02-26 04:04:19 +08:00
|
|
|
{
|
2020-03-24 22:17:25 +08:00
|
|
|
if (!wcscmp(notifications::TOAST_ACTIVATED_LAUNCH_ARG, cmd_arg_list[i]))
|
|
|
|
{
|
2020-02-26 04:04:19 +08:00
|
|
|
return SpecialMode::Win32ToastNotificationCOMServer;
|
2020-03-24 22:17:25 +08:00
|
|
|
}
|
|
|
|
else if (n_cmd_args == 2 && !wcsncmp(PT_URI_PROTOCOL_SCHEME, cmd_arg_list[i], wcslen(PT_URI_PROTOCOL_SCHEME)))
|
|
|
|
{
|
|
|
|
return SpecialMode::ToastNotificationHandler;
|
|
|
|
}
|
2020-04-21 15:30:12 +08:00
|
|
|
else if (n_cmd_args == 2 && !wcscmp(UPDATE_REPORT_SUCCESS, cmd_arg_list[i]))
|
|
|
|
{
|
|
|
|
return SpecialMode::ReportSuccessfulUpdate;
|
|
|
|
}
|
2020-02-26 04:04:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return SpecialMode::None;
|
|
|
|
}
|
|
|
|
|
|
|
|
int win32_toast_notification_COM_server_mode()
|
|
|
|
{
|
|
|
|
notifications::run_desktop_app_activator_loop();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-24 22:17:25 +08: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 18:43:09 +08:00
|
|
|
const std::wstring_view cant_drag_elevated_disable = L"cant_drag_elevated_disable/";
|
2020-10-20 06:27:24 +08:00
|
|
|
const std::wstring_view couldnt_toggle_powerpreview_modules_disable = L"couldnt_toggle_powerpreview_modules_disable/";
|
2020-06-23 20:53:02 +08:00
|
|
|
const std::wstring_view download_and_install_update = L"download_and_install_update/";
|
2020-10-20 06:27:24 +08:00
|
|
|
const std::wstring_view open_settings = L"open_settings/";
|
|
|
|
const std::wstring_view schedule_update = L"schedule_update/";
|
|
|
|
const std::wstring_view update_now = L"update_now/";
|
2020-06-18 18:43:09 +08:00
|
|
|
|
|
|
|
if (param == cant_drag_elevated_disable)
|
2020-03-24 22:17:25 +08:00
|
|
|
{
|
2020-10-20 06:27:24 +08:00
|
|
|
return notifications::disable_toast(notifications::CantDragElevatedDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error;
|
2020-03-24 22:17:25 +08:00
|
|
|
}
|
2020-06-18 18:43:09 +08:00
|
|
|
else if (param.starts_with(update_now))
|
2020-04-21 15:30:12 +08:00
|
|
|
{
|
2020-06-18 18:43:09 +08:00
|
|
|
std::wstring args{ UPDATE_NOW_LAUNCH_STAGE1_CMDARG };
|
|
|
|
const auto installerFilename = param.data() + size(update_now);
|
|
|
|
args += L' ';
|
|
|
|
args += installerFilename;
|
|
|
|
launch_action_runner(args.c_str());
|
2020-04-21 15:30:12 +08:00
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
}
|
2020-06-18 18:43:09 +08:00
|
|
|
else if (param.starts_with(schedule_update))
|
2020-04-21 15:30:12 +08:00
|
|
|
{
|
2020-06-18 18:43:09 +08:00
|
|
|
const auto installerFilename = param.data() + size(schedule_update);
|
|
|
|
UpdateState::store([=](UpdateState& state) {
|
2020-04-21 15:30:12 +08:00
|
|
|
state.pending_update = true;
|
2020-06-18 18:43:09 +08:00
|
|
|
state.pending_installer_filename = installerFilename;
|
2020-04-21 15:30:12 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
}
|
2020-06-23 20:53:02 +08:00
|
|
|
else if (param.starts_with(download_and_install_update))
|
|
|
|
{
|
2020-07-30 23:32:50 +08:00
|
|
|
try
|
|
|
|
{
|
2020-10-23 00:02:59 +08:00
|
|
|
std::wstring installer_filename = updating::download_update(Strings).get();
|
2020-07-28 00:53:29 +08:00
|
|
|
|
2020-07-30 23:32:50 +08:00
|
|
|
std::wstring args{ UPDATE_NOW_LAUNCH_STAGE1_CMDARG };
|
|
|
|
args += L' ';
|
|
|
|
args += installer_filename;
|
|
|
|
launch_action_runner(args.c_str());
|
2020-06-23 20:53:02 +08:00
|
|
|
|
2020-07-30 23:32:50 +08:00
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
MessageBoxW(nullptr,
|
2020-10-23 00:02:59 +08:00
|
|
|
GET_RESOURCE_STRING(IDS_DOWNLOAD_UPDATE_ERROR).c_str(),
|
2020-07-30 23:32:50 +08:00
|
|
|
L"PowerToys",
|
|
|
|
MB_ICONWARNING | MB_OK);
|
|
|
|
|
|
|
|
return toast_notification_handler_result::exit_error;
|
|
|
|
}
|
2020-06-23 20:53:02 +08:00
|
|
|
}
|
2020-10-20 06:27:24 +08: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)
|
|
|
|
{
|
|
|
|
open_menu_from_another_instance();
|
|
|
|
return toast_notification_handler_result::exit_success;
|
|
|
|
}
|
2020-03-24 22:17:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return toast_notification_handler_result::exit_error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
|
|
|
{
|
2020-02-26 04:04:19 +08:00
|
|
|
winrt::init_apartment();
|
2020-08-06 00:06:50 +08: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-26 04:04:19 +08:00
|
|
|
|
2020-04-21 15:30:12 +08:00
|
|
|
if (launch_pending_update())
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2020-11-18 18:15:14 +08:00
|
|
|
|
2020-03-24 22:17:25 +08: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-26 04:04:19 +08:00
|
|
|
{
|
|
|
|
case SpecialMode::Win32ToastNotificationCOMServer:
|
|
|
|
return win32_toast_notification_COM_server_mode();
|
2020-03-24 22:17:25 +08: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;
|
|
|
|
}
|
2020-04-21 15:30:12 +08:00
|
|
|
case SpecialMode::ReportSuccessfulUpdate:
|
2020-10-20 19:00:06 +08:00
|
|
|
{
|
2020-12-18 00:34:55 +08:00
|
|
|
notifications::remove_toasts_by_tag(notifications::UPDATING_PROCESS_TOAST_TAG);
|
|
|
|
notifications::remove_all_scheduled_toasts();
|
2020-10-23 00:02:59 +08:00
|
|
|
notifications::show_toast(GET_RESOURCE_STRING(IDS_PT_UPDATE_MESSAGE_BOX_TEXT),
|
2020-10-20 19:00:06 +08:00
|
|
|
L"PowerToys",
|
|
|
|
notifications::toast_params{ notifications::UPDATING_PROCESS_TOAST_TAG });
|
2020-04-21 15:30:12 +08:00
|
|
|
break;
|
2020-10-20 19:00:06 +08:00
|
|
|
}
|
2020-04-21 15:30:12 +08:00
|
|
|
|
2020-02-26 04:04:19 +08:00
|
|
|
case SpecialMode::None:
|
|
|
|
// continue as usual
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-02-21 18:12:04 +08:00
|
|
|
wil::unique_mutex_nothrow msi_mutex;
|
|
|
|
wil::unique_mutex_nothrow msix_mutex;
|
|
|
|
|
|
|
|
if (winstore::running_as_packaged())
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-02-21 18:12:04 +08:00
|
|
|
msix_mutex = create_msix_mutex();
|
|
|
|
if (!msix_mutex)
|
|
|
|
{
|
|
|
|
// The MSIX version is already running.
|
2020-04-07 18:17:18 +08:00
|
|
|
open_menu_from_another_instance();
|
2020-02-21 18:12:04 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2020-02-18 23:11:01 +08:00
|
|
|
|
2020-02-21 18:12:04 +08:00
|
|
|
// Check if the MSI version is running, if not, hold the
|
|
|
|
// mutex to prevent the old MSI versions to start.
|
|
|
|
msi_mutex = create_msi_mutex();
|
|
|
|
if (!msi_mutex)
|
|
|
|
{
|
|
|
|
// The MSI version is running, warn the user and offer to uninstall it.
|
|
|
|
const bool declined_uninstall = !start_msi_uninstallation_sequence();
|
|
|
|
if (declined_uninstall)
|
|
|
|
{
|
|
|
|
// Check again if the MSI version is still running.
|
|
|
|
msi_mutex = create_msi_mutex();
|
|
|
|
if (!msi_mutex)
|
|
|
|
{
|
2020-04-07 18:17:18 +08:00
|
|
|
open_menu_from_another_instance();
|
2020-02-21 18:12:04 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Older MSI versions are not aware of the MSIX mutex, therefore
|
|
|
|
// hold the MSI mutex to prevent an old instance to start.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2020-02-18 23:11:01 +08:00
|
|
|
{
|
2020-02-21 18:12:04 +08:00
|
|
|
// Check if another instance of the MSI version is already running.
|
|
|
|
msi_mutex = create_msi_mutex();
|
|
|
|
if (!msi_mutex)
|
|
|
|
{
|
|
|
|
// The MSI version is already running.
|
2020-04-07 18:17:18 +08:00
|
|
|
open_menu_from_another_instance();
|
2020-02-21 18:12:04 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2020-02-18 23:11:01 +08:00
|
|
|
|
2020-02-21 18:12:04 +08:00
|
|
|
// Check if an instance of the MSIX version is already running.
|
|
|
|
// Note: this check should always be negative since the MSIX version
|
|
|
|
// is holding both mutexes.
|
|
|
|
msix_mutex = create_msix_mutex();
|
|
|
|
if (!msix_mutex)
|
2020-02-18 23:11:01 +08:00
|
|
|
{
|
2020-02-21 18:12:04 +08:00
|
|
|
// The MSIX version is already running.
|
2020-04-07 18:17:18 +08:00
|
|
|
open_menu_from_another_instance();
|
2020-02-18 23:11:01 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2020-02-21 18:12:04 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// The MSIX version isn't running, release the mutex.
|
|
|
|
msix_mutex.reset(nullptr);
|
|
|
|
}
|
2020-02-18 23:11:01 +08:00
|
|
|
}
|
|
|
|
|
2019-12-27 00:26:11 +08: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-17 01:36:52 +08:00
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
auto general_settings = load_general_settings();
|
2020-06-27 05:46:47 +08: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);
|
2019-12-27 00:26:11 +08:00
|
|
|
int rvalue = 0;
|
2020-03-24 22:17:25 +08:00
|
|
|
const bool elevated = is_process_elevated();
|
|
|
|
if ((elevated ||
|
|
|
|
general_settings.GetNamedBoolean(L"run_elevated", false) == false ||
|
|
|
|
strcmp(lpCmdLine, "--dont-elevate") == 0))
|
2019-12-27 00:26:11 +08:00
|
|
|
{
|
2020-03-24 22:17:25 +08:00
|
|
|
result = runner(elevated);
|
2019-12-27 00:26:11 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
schedule_restart_as_elevated();
|
|
|
|
result = 0;
|
|
|
|
}
|
2019-12-17 01:36:52 +08:00
|
|
|
}
|
2019-12-27 00:26:11 +08:00
|
|
|
catch (std::runtime_error& err)
|
|
|
|
{
|
|
|
|
std::string err_what = err.what();
|
2020-01-10 01:17:42 +08: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-27 00:26:11 +08:00
|
|
|
result = -1;
|
2019-12-17 01:36:52 +08:00
|
|
|
}
|
2020-02-21 18:12:04 +08:00
|
|
|
|
|
|
|
// We need to release the mutexes to be able to restart the application
|
|
|
|
if (msi_mutex)
|
|
|
|
{
|
|
|
|
msi_mutex.reset(nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (msix_mutex)
|
|
|
|
{
|
|
|
|
msix_mutex.reset(nullptr);
|
|
|
|
}
|
|
|
|
|
2019-12-27 00:26:11 +08:00
|
|
|
if (is_restart_scheduled())
|
|
|
|
{
|
|
|
|
if (restart_if_scheduled() == false)
|
|
|
|
{
|
|
|
|
auto text = is_process_elevated() ? GET_RESOURCE_STRING(IDS_COULDNOT_RESTART_NONELEVATED) :
|
|
|
|
GET_RESOURCE_STRING(IDS_COULDNOT_RESTART_ELEVATED);
|
2020-01-10 01:17:42 +08:00
|
|
|
MessageBoxW(nullptr, text.c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
|
|
|
|
|
|
|
|
restart_same_elevation();
|
2019-12-27 00:26:11 +08:00
|
|
|
result = -1;
|
|
|
|
}
|
2019-12-17 01:36:52 +08:00
|
|
|
}
|
2019-12-27 00:26:11 +08:00
|
|
|
stop_tray_icon();
|
|
|
|
return result;
|
2019-12-17 01:36:52 +08:00
|
|
|
}
|