切换到拥有句柄的进程
Switch to process that owns a handle
我正在处理的 Windows 应用程序必须是单实例。目前我可以通过创建一个命名的互斥锁并检查它是否已经存在来实现这一点:
CreateMutexW(NULL, TRUE, L"MY_UNIQUE_APP_IDENTIFIER");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// error message here and exit
}
现在,我想避开该消息,只切换到现有实例并关闭重复的实例。
我考虑过使用 SetForegroundWindow
HWND hWnd = /* somehow find the HWND of the process owning the mutex*/;
if (hWnd) {
::SetForegroundWindow(hWnd);
}
也许使用互斥量的句柄来定位最初拥有它的进程,然后寻找它的 main window(对于最后一步我可能使用 this)?
我还没有找到进行句柄到进程搜索的方法,只能listing all processes and then listing all their handles寻找互斥体,但听起来效率很低。
有更好的方法吗?句柄到进程搜索还是切换到给定互斥句柄的进程?
根据评论的建议,最终解决方案不使用互斥处理程序,而是使用 windows' 名称(感谢指导):
void checkForAnotherInstanceAndSwitch()
{
CreateMutexW(NULL, true, L"MY_UNIQUE_APP_IDENTIFIER");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
const auto hWnd = ::FindWindowW(nullptr, L"MY_UNIQUE_WINDOW_NAME");
if (hWnd) { // switch to the other instance
::SetForegroundWindow(hWnd);
} else { // something went wrong and could not find the other instance
// for example, windows name contains 'BETA' suffix while the other instance doesn't
// Show message box "You are already running this application."
}
exit(0);
}
}
我正在处理的 Windows 应用程序必须是单实例。目前我可以通过创建一个命名的互斥锁并检查它是否已经存在来实现这一点:
CreateMutexW(NULL, TRUE, L"MY_UNIQUE_APP_IDENTIFIER");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// error message here and exit
}
现在,我想避开该消息,只切换到现有实例并关闭重复的实例。
我考虑过使用 SetForegroundWindow
HWND hWnd = /* somehow find the HWND of the process owning the mutex*/;
if (hWnd) {
::SetForegroundWindow(hWnd);
}
也许使用互斥量的句柄来定位最初拥有它的进程,然后寻找它的 main window(对于最后一步我可能使用 this)?
我还没有找到进行句柄到进程搜索的方法,只能listing all processes and then listing all their handles寻找互斥体,但听起来效率很低。
有更好的方法吗?句柄到进程搜索还是切换到给定互斥句柄的进程?
根据评论的建议,最终解决方案不使用互斥处理程序,而是使用 windows' 名称(感谢指导):
void checkForAnotherInstanceAndSwitch()
{
CreateMutexW(NULL, true, L"MY_UNIQUE_APP_IDENTIFIER");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
const auto hWnd = ::FindWindowW(nullptr, L"MY_UNIQUE_WINDOW_NAME");
if (hWnd) { // switch to the other instance
::SetForegroundWindow(hWnd);
} else { // something went wrong and could not find the other instance
// for example, windows name contains 'BETA' suffix while the other instance doesn't
// Show message box "You are already running this application."
}
exit(0);
}
}