There is a design pattern called Singleton that usually applies only to classes. But imho it can also be applied to applications to prevent the user from starting several instances of the application. I came along this article on DelphiAboutCom which shows how to create a single instance application. Unfortunately it doesn’t work.

What is going on?

If you run this application a second time it seems to work. But if you close all applications and then try to rerun it you have a problem because Atoms are not deleted automatically. You have to call GlobalDeleteAtom for every GlobalAddAtom. MSDN on GlobalAddAtom reads:

Global atoms are not deleted automatically when the application terminates. For every call to the GlobalAddAtom function, there must be a corresponding call to the GlobalDeleteAtom function.

So you may think that the code is correct if you add a GlobalDeleteAtom. Well, if you also add a try/finally block then you are correct.

var hAtom : THandle;
begin
  if 0 <> GlobalFindAtom('xx')
    ExitWithAMessage;

  hAtom := GlobalAddAtom('xx');
  try
    Application.CreateForm(TFormMain, FormMain) ;
    Application.Run;
  finally
    GlobalDeleteAtom(hAtom);
  end;

(I omitted error checks for readability)

This looks good. However you should know that Atoms are not session (=Terminal Session = Logonuser session) wide! Each Windowstation (like the famous “Winsta0″) has its own global atom table. So this check fails if you run your application in another Windowstation.  This case is very rare because other Windowstations do not have access to the local keyboard and graphic interface. So only applications with a remote control and without GUI can run there. But if you ever come into this situation do not use Atoms!

Instead use Mutexes:

Using Mutexes is an easier and more modern way than the atoms from 16-bit era. We have a really good advantage here:

Windows removes the mutex if there is no open handle anymore available. So even if you do not close the handle yourself – and you don’t need to do it because Windows does it on exit – the mutex will be destroyed and a second run of your application will succeed.

uses
 Windows,
 SyncObjs,
 SysUtils;

var
 SingleAppMutex : THandle;
begin
 SingleAppMutex := CreateMutex(nil, True, PChar('{1CF7FD3B-4225-400A-B668-118FAD8A483B}'));
 if GetLastError() = ERROR_ALREADY_EXISTS then
   exit;

As you can see, I’m using a GUID to create a named mutex. This is very handy because it is very unlikely that another application uses such a name (even if it is a GUID) by accident.

You can generate a GUID from within Delphi if you hit Ctrl+Shift+G.