How to restart a VCL Delphi application while using a Mutex

How to restart a VCL Delphi application while using a Mutex. This article puts all of the research in one single page.

Using a mutex prevents multiple application instances from occurring.

You may wonder why would you wish to restart an application. It doesn’t mean there was a software defect in the code. Application settings have changed.

What is a mutex

A mutex object is a synchronization mechanism designed to ensure mutually exclusive access to a single resource that is shared among a set of kernel-mode threads.

Using a mutex can ensure that there is only one instance of your application executing. A unique name should be used when starting the application.

The simplest way is to use your application name and/or a shorten name that would be unique when creating the mutex .

Simple but true.

The mutex should be released as well as closed.

Mutex Functions

  • CreateMutex creates a new mutex object with specified name.
  • OpenMutex will get the handle to already running mutex by its name.
  • WaitForSingleObject waits for ownership to the mutex.
  • ReleaseMutex will release ownership of the mutex.
  • CloseHandle closes the mutex handle and destroys it.

How to insert the logic into a Delphi application

There is a brilliant piece of code that creates a mutex and allows the application to restart after an update or modification. You can view the original comments by clicking here.

In Delphi, you can view the source for the program within the IDE.

Enter the uCreateMutex unit in the uses section. Upon starting the application the unit will create the mutex.

uses
...
uCreateMutex in 'uCreateMutex.pas';

{$R *.res}

begin
     if uCreateMutex.Active = True then
     begin
     ...  Any code for splash screen, data module creation, etc.
     end; // end of program.
The following code can be placed in a unit so that it is a reusable function.

The Restart flag must be set to true.
You can terminate the application and use ProcessMessages to permit the application to process messages that are currently in the message queue. Only affects this application and nothing else.

function ObjectName.restart : boolean;
 begin
   uCreateMutex.Restart := True;
   Application.Terminate;
   Application.ProcessMessages;
 end;
You can name the unit to whatever you want.  Since the original developer had this name, i decided to use it.

unit uCreateMutex;
interface

// Restart is set to false unless an event triggers a change.
// Active is what allows to know if the application is ready to go.
var
  Restart: boolean = false;
  Active : Boolean = False;

implementation


uses forms, Windows, Messages, SysUtils, Classes, ShellApi, Dialogs;

var
  MutexHandle: cardinal;
  AppName: PChar;
const
  ID = 'ANY UNIQUE NAME YOU WANT';

initialization
// Upon the application starting. The mutex is created with the ID made above.
  MutexHandle := CreateMutex (nil, False, PChar (ID));

// The mutex is tested if someone tries to start another instance.
  if (GetLastError = ERROR_ALREADY_EXISTS) then
  begin
// Fancy message and set the active flag to false.
    ShowMessage('YO YOUR APPLICATION is running already!');
    Active := False;
// I removed the Halt since that is not a clean way of exiting.
// terminating and process any messages in the queue is much cleaner.
    exit;
  end
// Otherwise the active flag is set to ON.
  else
    Active := True;

finalization
// If the Application closes for some reason the mutex is released.
// I placed the closing of the mutex handle to clean up the environment.
  ReleaseMutex(MutexHandle);
   CloseHandle(MutexHandle);
// If the restart flag is set due to any form of update to registry, 
// settings or the application itself, then it will restart again.
  if Restart then
  begin
    AppName := PChar(Application.ExeName);
    ShellExecute(0,'open', AppName, nil, nil, SW_SHOWNORMAL) ;
  end;

end.
Baron Software

This works without any major repercussions on the application. The software code above demonstrates how to cleanly terminate, restart and stop multiple instances. You can review the original article and apply this freely in your applications.