0

The Windows application I'm working on has to be single-instance. Currently I'm able to achieve this by creating a named mutex and checking if it already exists:

CreateMutexW(NULL, TRUE, L"MY_UNIQUE_APP_IDENTIFIER");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
   // error message here and exit
}

Now, I'd like to avoid the message and just switch to the existing instance and close the duplicate one.

I've thought on using SetForegroundWindow

HWND hWnd = /* somehow find the HWND of the process owning the mutex*/;
if (hWnd) {
  ::SetForegroundWindow(hWnd);
}

Maybe using the handle of the mutex to locate the process that initially owned it and then looking for its main window (for this last step I may use this)?

I haven't find a way to make a handle-to-process search, only listing all processes and then listing all their handles, looking for the mutex, but as it sounds it seems very inefficient.

Is there a better way to do this? Either the handle-to-process search or the switch to process given the mutex handle?

cbuchart
  • 10,847
  • 9
  • 53
  • 93
  • 1
    Given that you (presumably) know the name of the process you can just search processes with that name for the handle? Alternatively write the pid of the owning process into shared memory – Alan Birtles Jul 30 '19 at 08:18
  • 1
    I think finding handle of main process is easy, just search by (unique) window class name. – user7860670 Jul 30 '19 at 08:19
  • Mmm... probably both of you are right and I'm over-complicating myself. I'll take a look to those options, thanks! – cbuchart Jul 30 '19 at 08:23

1 Answers1

0

Following the suggestions from comments, the final solution doesn't use the mutex handler, but the windows' name (thanks for the guidance):

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);
  }
}
cbuchart
  • 10,847
  • 9
  • 53
  • 93