mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 05:06:36 +02:00
Runner check for MSI and MSIX (#1345)
* Add startup check for the MSI version of PT * Alert if another instance of PowerToys is already running
This commit is contained in:
@@ -56,6 +56,16 @@ wil::unique_mutex_nothrow create_runner_mutex(const bool msix_version)
|
|||||||
return GetLastError() == ERROR_ALREADY_EXISTS ? wil::unique_mutex_nothrow{} : std::move(result);
|
return GetLastError() == ERROR_ALREADY_EXISTS ? wil::unique_mutex_nothrow{} : std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wil::unique_mutex_nothrow create_msi_mutex()
|
||||||
|
{
|
||||||
|
return create_runner_mutex(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
wil::unique_mutex_nothrow create_msix_mutex()
|
||||||
|
{
|
||||||
|
return create_runner_mutex(true);
|
||||||
|
}
|
||||||
|
|
||||||
bool start_msi_uninstallation_sequence()
|
bool start_msi_uninstallation_sequence()
|
||||||
{
|
{
|
||||||
const auto package_path = get_msi_package_path();
|
const auto package_path = get_msi_package_path();
|
||||||
@@ -87,6 +97,14 @@ bool start_msi_uninstallation_sequence()
|
|||||||
return exit_code == 0;
|
return exit_code == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void alert_already_running()
|
||||||
|
{
|
||||||
|
MessageBoxW(nullptr,
|
||||||
|
GET_RESOURCE_STRING(IDS_ANOTHER_INSTANCE_RUNNING).c_str(),
|
||||||
|
GET_RESOURCE_STRING(IDS_POWERTOYS).c_str(),
|
||||||
|
MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND);
|
||||||
|
}
|
||||||
|
|
||||||
int runner(bool isProcessElevated)
|
int runner(bool isProcessElevated)
|
||||||
{
|
{
|
||||||
DPIAware::EnableDPIAwarenessForThisProcess();
|
DPIAware::EnableDPIAwarenessForThisProcess();
|
||||||
@@ -149,28 +167,69 @@ int runner(bool isProcessElevated)
|
|||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
auto msix_mutex = create_runner_mutex(true);
|
wil::unique_mutex_nothrow msi_mutex;
|
||||||
const bool msix_mutex_failed_to_lock = !msix_mutex;
|
wil::unique_mutex_nothrow msix_mutex;
|
||||||
if (msix_mutex_failed_to_lock)
|
|
||||||
{
|
|
||||||
// The app is already running
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto msi_mutex = create_runner_mutex(false);
|
if (winstore::running_as_packaged())
|
||||||
const bool msi_mutex_already_taken = !msi_mutex;
|
|
||||||
if (msi_mutex_already_taken)
|
|
||||||
{
|
{
|
||||||
const bool declined_uninstall = !start_msi_uninstallation_sequence();
|
msix_mutex = create_msix_mutex();
|
||||||
|
if (!msix_mutex)
|
||||||
if (declined_uninstall)
|
|
||||||
{
|
{
|
||||||
// Warn and exit if msi version is already running
|
// The MSIX version is already running.
|
||||||
notifications::show_toast(localized_strings::MSI_VERSION_IS_ALREADY_RUNNING);
|
alert_already_running();
|
||||||
// Wait 1 second before exiting, since if we exit immediately, the toast notification becomes lost
|
|
||||||
Sleep(1000);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
alert_already_running();
|
||||||
|
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
|
||||||
|
{
|
||||||
|
// 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.
|
||||||
|
alert_already_running();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// The MSIX version is already running.
|
||||||
|
alert_already_running();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The MSIX version isn't running, release the mutex.
|
||||||
|
msix_mutex.reset(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@@ -213,9 +272,18 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR);
|
MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR);
|
||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
// We need to release mutices to be able to restart the application
|
|
||||||
msi_mutex.reset(nullptr);
|
// We need to release the mutexes to be able to restart the application
|
||||||
msix_mutex.reset(nullptr);
|
if (msi_mutex)
|
||||||
|
{
|
||||||
|
msi_mutex.reset(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msix_mutex)
|
||||||
|
{
|
||||||
|
msix_mutex.reset(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_restart_scheduled())
|
if (is_restart_scheduled())
|
||||||
{
|
{
|
||||||
if (restart_if_scheduled() == false)
|
if (restart_if_scheduled() == false)
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
#define APPICON 101
|
#define APPICON 101
|
||||||
#define ID_TRAY_MENU 102
|
#define ID_TRAY_MENU 102
|
||||||
#define IDS_COULDNOT_RESTART_NONELEVATED 103
|
|
||||||
#define IDS_COULDNOT_RESTART_ELEVATED 104
|
#define IDS_POWERTOYS 103
|
||||||
#define IDS_ERROR 105
|
#define IDS_ERROR 104
|
||||||
|
#define IDS_COULDNOT_RESTART_NONELEVATED 105
|
||||||
|
#define IDS_COULDNOT_RESTART_ELEVATED 106
|
||||||
|
#define IDS_ANOTHER_INSTANCE_RUNNING 107
|
||||||
|
|
||||||
#define ID_EXIT_MENU_COMMAND 40001
|
#define ID_EXIT_MENU_COMMAND 40001
|
||||||
#define ID_SETTINGS_MENU_COMMAND 40002
|
#define ID_SETTINGS_MENU_COMMAND 40002
|
||||||
#define ID_ABOUT_MENU_COMMAND 40003
|
#define ID_ABOUT_MENU_COMMAND 40003
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user