Releasing a mutex created on startup within the same application

Viewed 214

I create a mutex at the start of the my application, primarily to prevent running 2 instances of same application.

  if CreateMutex(nil,false,'Proton Studio') = 0 then
    RaiseLastOSError;
  if GetLastError = ERROR_ALREADY_EXISTS then exit;

However, when I reconfigure my application I need to release the mutex before the application is closed in order to start a short program which will then restart my application.

  hw := OpenMutex(MUTEX_ALL_ACCESS, false, 'Proton Studio');
  if ReleaseMutex(hw)then begin
    if ShellExecute(application.Handle, 'open',
    Pchar('StudioRestart.exe'), PChar(Application.ExeName),'', SW_SHOWNORMAL) > 32 then
      fmIDEMain.Close
    else
      ShowMessage('Unable to Restart, please close and restart manually')
  end

OpenMutex returns a handle but when I call ReleaseMutex the function returns false. How should I close this mutex?

1 Answers

You seem to use the existence of the mutex as the criterion to decide whether the process already runs and not who owns the mutex. ReleaseMutex is used to give up ownership of a mutex if you currently own it. But your code doesn't actually retrieve ownership of the mutex anywhere.

I see these ways towards solving your problem:

  1. Destroy mutex instead of trying to release it.

Instead of using ReleaseMutex, use CloseHandle to destroy the mutex. If you are the only one holding a handle to the mutex, it will be gone afterwards.

For this purpose, remember the original handle returned by CreateMutex and don't open the mutex a second time.

  1. Use mutexes as intended

Instead of using the mere existing of the mutex, try to obtain ownership by calling WaitForSingleObject on it. You can then release it by calling ReleaseMutex.

  1. External program should wait (my preferred method)

Have the external program wait until the old instance of the application was fully terminated before trying to start a new instance.

Related