Search code examples
delphipersistencemutexinstancesemaphore

How can I tell if another instance of my program is already running?


How do i tell if one instance of my program is running? I thought I could do this with a data file but it would just be messy :(

I want to do this as I only want 1 instance to ever be open at one point.


Solution

  • You can create a Semaphore and stop execution (put the code into your *.dpr file) and bring you running application to the screen.

    var
      Semafor: THandle;
    
    begin
      { Don't start twice ... if already running bring this instance to front }
      Semafor := CreateSemaphore(nil, 0, 1, 'MY_APPLICATION_IS_RUNNING');
      if ((Semafor <> 0) and { application is already running }
         (GetLastError = ERROR_ALREADY_EXISTS)) then 
      begin
        RestoreWindow('TMyApplication');
        CloseHandle(Semafor);
        Halt;
      end;
    
      Application.CreateForm(....);    
      Application.Initialize;
      Application.Run;
      CloseHandle(Semafor);
    end;
    

    EDIT (added the RestoreWindow method):

    The aFormName is the name of your main form class in your application.

    procedure RestoreWindow(aFormName: string);
    var
      Wnd,
      App: HWND;    
    begin
      Wnd := FindWindow(PChar(aFormName), nil);
      if (Wnd <> 0) then 
      begin { Set Window to foreground }
        App := GetWindowLong(Wnd, GWL_HWNDPARENT);
        if IsIconic(App) then 
          ShowWindow(App, SW_RESTORE);
    
        SetForegroundwindow(App);
      end;
    end;