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 .
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.
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.
You must be logged in to post a comment.