Jump to content




Recent Status Updates

  • Photo
      15 Nov
    duzamucha

    Hi, I am final year Interior Design Student from University of Huddersfield. I am currently working on my final major project which is going to be linked to coding. I was hoping that you could help me with my research. I have prepared a short survey, it would be a massive help if you could fill it in for me. It takes less than 2 minutes to complete, I promise. Here is the link: https://www.surveymonkey.com/s/73XLJKK Thank you so much in advance!

View All Updates

Developed by TechBiz Xccelerator
Photo
- - - - -

Prevent Multiple Instance of a Program (using Mutex)

pseudocode

  • Please log in to reply
3 replies to this topic

#1 Luthfi

Luthfi

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,320 posts
  • Programming Language:PHP, Delphi/Object Pascal, Pascal, Transact-SQL
  • Learning:C, Java, PHP

Posted 30 January 2011 - 04:12 AM

There are often times we want to make sure that at any given time there is only one instance of our program running. Many solutions available for this problem. Some of them:

  • Find process in process list
  • Find window name
  • Checking existence and status (locked or free) of a file
  • Using OS flags

My favorite is using OS flags, since in my opinion it's the simplest from all the methods. And from several OS flags (or several features that can be used as a flag) provided by Windows, Mutex is my favorite one. You can read more details abut mutex here.

Mutex: The Basics

Quoted from msdn article:

You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes. Each thread must wait for ownership of the mutex before it can execute the code that accesses the shared resource. For example, if several threads share access to a database, the threads can use a mutex object to permit only one thread at a time to write to the database.


From the excerpt above we can deduce that an application can create mutex that unique and detectable from other applications. Therefore we should detect our mutex before move onto the main code of a program. If the mutex exists we should terminate the current process, otherwise we create the mutex ourselves and continue to main code.

The creator of the mutex (i.e. the first instance) must destroy or release the mutex when it is terminated. This is to make sure that the mutex does not exist anymore, so the next first instance of our program can create the mutex successfully. However it's just a good practice. Because Windows actually keeps records of mutex owner. Once the owner got terminated, the mutex will also be destroyed.

Our pseudocode is:
begin
  if MutexIsExists(OurMutexID) then
    Terminate
  else begin
    CreateMutex(OurMutexID);
    Goto MainProgram;
    DestroyMutex;
  end;
end;

Code Implementation

For this tutorial in dealing with mutex we'll be relying on windows api CreateMutex. Official details of CreateMutex is available here.

To check the existence of a mutex we have to call CreateMutex to create a mutex with a specific name, and set us (the caller) as the owner of the mutex. If mutex with the same name already exists, CreateMutex can not set us as the owner and it will raise error with code ERROR_ALREADY_EXISTS (183). If it does not exist, then CreateMutex will succesfully create the mutex and return the handle of the mutex.

In Delphi project, the best place to put the checking code is in .dpr file, immediately after enter the main begin...end block. But this is not mandatory, you can put the checking code in any other place that you want according to specific requirements.

Here is the sample code, in this tutorial we want to show a message before terminating if the same program is already running.

program SingleInstance;

uses
  Windows,
  Forms,
  Dialogs,
  Main_SingleInstance in 'Main_SingleInstance.pas' {Form1};

{$R *.res}

const
  MutexName        = 'CodeCall.Net Mutex';
resourcestring
  DUPLICATE_MSG    = 'Another instance of this program is already running. This one will shutdown';
var
  vMutex: THandle;
begin
  // try to create our mutex
  vMutex := CreateMutex(nil, True, MutexName);

  // check if the previous line caused error and the error is ERROR_ALREADY_EXISTS
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    // show the duplication message
    MessageDlg(DUPLICATE_MSG, mtError, [mbOk], 0);
    Exit;  // terminates the program
  end;
  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  finally
    // release the mutex
    CloseHandle(vMutex);
  end;
end.

After compilation, let's try the demo program. First execute will nicely show our main form like this:

[ATTACH]3670[/ATTACH]

Now while the first one is still running, try to execute the same exe once again. This time it will show an error message like shown below. After we close the message, it will immediately terminate.

[ATTACH]3669[/ATTACH]

Full source code of the demo project is attached. Feel free to use or improve.

Attached Thumbnails

  • ScrShot_NextRun001.png
  • ScrShot_FirstRun001.png

Attached Files


Edited by LuthfiHakim, 20 March 2011 - 04:17 PM.
fixing code formatting and tag error

  • 0

#2 Alexander

Alexander

    YOL9

  • Moderator
  • 3,946 posts
  • Location:Vancouver, Eh! Cleverness: 200
  • Programming Language:C, C++, PHP, Assembly

Posted 30 January 2011 - 03:41 PM

Very nice tutorial, I am definitely digesting this when I understand a little more about Delphi, I am wishing to learn.
  • 0

All new problems require investigation, and so if errors are problems, try to learn as much as you can and report back.


#3 Luthfi

Luthfi

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1,320 posts
  • Programming Language:PHP, Delphi/Object Pascal, Pascal, Transact-SQL
  • Learning:C, Java, PHP

Posted 30 January 2011 - 11:29 PM

Thank you, Alex! Let me know if you need help learning Delphi. You already did help me a lot in learning PHP! :c-thumbup:
  • 0

#4 rolakyng

rolakyng

    CC Lurker

  • Just Joined
  • Pip
  • 1 posts

Posted 14 February 2011 - 10:10 AM

There are often times we want to make sure that at any given time there is only one instance of our program running. Many solutions available for this problem. Some of them:

  • Find process in process list
  • Find window name
  • Checking existence and status (locked or free) of a file
  • Using OS flags

My favorite is using OS flags, since in my opinion it's the simplest from all the methods. And from several OS flags (or several features that can be used as a flag) provided by Windows, Mutex is my favorite one. You can read more details abut mutex here.

Mutex: The Basics

Quoted from msdn article:


From the excerpt above we can deduce that an application can create mutex that unique and detectable from other applications. Therefore we should detect our mutex before move onto the main code of a program. If the mutex exists we should terminate the current process, otherwise we create the mutex ourselves and continue to main code.

The creator of the mutex (i.e. the first instance) must destroy or release the mutex when it is terminated. This is to make sure that the mutex does not exist anymore, so the next first instance of our program can create the mutex successfully. However it's just a good practice. Because Windows actually keeps records of mutex owner. Once the owner got terminated, the mutex will also be destroyed.

Our pseudocode is:
begin
  if MutexIsExists(OurMutexID) then
    Terminate
  else begin
    CreateMutex(OurMutexID);
    Goto MainProgram;
    DestroyMutex;
  end;
end;

Code Implementation

For this tutorial in dealing with mutex we'll be relying on windows api CreateMutex. Official details of CreateMutex is available here.

To check the existence of a mutex we have to call CreateMutex to create a mutex with a specific name, and set us (the caller) as the owner of the mutex. If mutex with the same name already exists, CreateMutex can not set us as the owner and it will raise error with code ERROR_ALREADY_EXISTS (183). If it does not exist, then CreateMutex will succesfully create the mutex and return the handle of the mutex.

In Delphi project, the best place to put the checking code is in .dpr file, immediately after enter the main begin...end block. But this is not mandatory, you can put the checking code in any other place that you want according to specific requirements.

Here is the sample code, in this tutorial we want to show a message before terminating if the same program is already running.

program SingleInstance;

uses
  Windows,
  Forms,
  Dialogs,
  Main_SingleInstance in 'Main_SingleInstance.pas' {Form1};

{$R *.res}

const
  MutexName        = 'CodeCall.Net Mutex';
resourcestring
  DUPLICATE_MSG    = 'Another instance of this program is already running. This one will shutdown';
var
  vMutex: THandle;
begin
  // try to create our mutex
  vMutex := CreateMutex(nil, True, MutexName);

  // check if the previous line caused error and the error is ERROR_ALREADY_EXISTS
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    // show the duplication message
    MessageDlg(DUPLICATE_MSG, mtError, [mbOk], 0);
    Exit;  // terminates the program
  end;
  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  finally
    // release the mutex
    CloseHandle(vMutex);
  end;
end.

After compilation, let's try the demo program. First execute will nicely show our main form like this:

[ATTACH]3670[/ATTACH]

Now while the first one is still running, try to execute the same exe once again. This time it will show an error message like shown below. After we close the message, it will immediately terminated.

[ATTACH]3669[/ATTACH]

Full source code of the demo project is attached. Feel free to use or improve.


Hey thanks a lot for post.
  • 0





Powered by binpress