Jump to content
amit

How to Prevent Multiple Instance Application Running.

Recommended Posts

I can use Mutex to prevent multiple instances app in VCL mode.    How to Prevent Multiple Instance Application Running in FMX?

Share this post


Link to post
4 hours ago, Fr0sT.Brutal said:

Mutex has nothing to do with VCL so you can use it for FMX as well

Are there cross platform implementations for Mutex in the RTL?

Otherwise it would not be restricted to the VCL but to Windows.

Share this post


Link to post

In 2017, there was an example on SO for Windows / OSX - not sure if it still is the appropriate way to do it?

https://stackoverflow.com/questions/13326292/only-one-application-instance-with-firemonkey

 

For iOS and Android - single instance is handled by the OS, isn't it?

 

Edit: There also is an interesting comment at the end of this thread
https://codeverge.com/embarcadero.delphi.firemonkey/only-one-application-instance-w/1049535

Share this post


Link to post
3 hours ago, dummzeuch said:

Are there cross platform implementations for Mutex in the RTL?

*shrug* Original Q didn't mention any platform req's

Share this post


Link to post

In a project file usually, I add that:
 

    // checks if application is already running
    AppplicationID := '{BFA11B69-B59C-40BA-BABB-724F2BF3AFE4}';
    RunOnceMutex := CreateMutex(nil, True, @ApplicationID[1]);
    if RunOnceMutex <> 0 then
    begin
      if GetLastError = ERROR_ALREADY_EXISTS then
      begin
        ShowErrorMessage
        (
          _('Application already running'),
          _('Press OK button to quit application'),
          _('Instance of this application is already running !'),
          _('For each computer, or virtual machine, is allowed to start a single instance of the Control Software. ' +
            'If you see this message it means that an application instance is already loaded and running.')
        );
        CloseHandle(RunOnceMutex);
        Halt;
      end
    end;

Take care to create a different UUID for every singleton application.

You can fastly create a new UUID pressing CTRL + SHIFT + G in Delphi IDE.

Edited by shineworld

Share this post


Link to post
4 hours ago, dummzeuch said:

Are there cross platform implementations for Mutex in the RTL?

Otherwise it would not be restricted to the VCL but to Windows.

Yes they are but not named so useless for the purpose

Quote

{$IFDEF POSIX}
procedure TSynchroObject.CheckNamed(const Name: string);
begin
  if Name <> '' then
    raise ESyncObjectException.CreateRes(@sNamedSyncObjectsNotSupported);
end;
{$ENDIF POSIX}

 

probably for *nix named pipes or file sockets should be used

Share this post


Link to post

I did not check for FMX

In VCL Easy use OgFirst in free "ONGUARD"

in DPR

begin
  if  TogFirst.IsFirstInstance  then
  begin
xxxxxxxxxx

xxxxxxxxxx

xxxxxxxxxxx

  end
  else TogFirst.ActivateFirstInstance;
 

Edited by limelect

Share this post


Link to post
2 hours ago, limelect said:

I did not check for FMX

In VCL Easy use OgFirst in free "ONGUARD"

in DPR

begin
  if  TogFirst.IsFirstInstance  then
  begin
xxxxxxxxxx

xxxxxxxxxx

xxxxxxxxxxx

  end
  else TogFirst.ActivateFirstInstance;
 

I can not understand why you have to have (free or paid) components for everything; unless true multiplatform is supported.

You can simply use WinApi:

handle := CreateMutex(nil, True, 'MyApplicationUniqueMutex');
Try
  If (handle = 0) Or (GetLastError = ERROR_ALREADY_EXISTS) Then
  Begin
    ShowMessage('Only one instance can be running at a time!');
    handle := FindWindow('TMyApplicationMainForm', nil);
    If IsWindow(handle) Then
    Begin
      ShowWindow(handle, SW_RESTORE And SW_SHOW);
      SetForegroundWindow(handle);
      SetFocus(handle);
    End;
    handle := 0;
    Exit;
  End;
  
  // Stuff from DPR... like Application.Run etc
  
Finally
 If handle <> 0 Then
   CloseHandle(handle);
End; 

End result is the same and you have smaller resource footprint.
 

Share this post


Link to post

I also use mutex (event in my case)+findwindow approach as the simplest solution but named pipes seem more advanced (didn't implemented them yet though)

- Same system- or user-wide unique named object

- Communication included for activating 1st instance with any data

- More reliable than Findwindow

- Suits for console apps, services

- Likely x-platform (at least for Linux)

  • Like 1

Share this post


Link to post

I use named pipes so that a starting second instance of my app can send the files and actions (from the command line) to the existing app.

  • Like 2

Share this post


Link to post
15 hours ago, David Hoyle said:

I use named pipes so that a starting second instance of my app can send the files and actions (from the command line) to the existing app.

How do you handle the default blocking nature of pipes? Or use it async-ly?

Share this post


Link to post

The named pipe sits in a thread and when triggered communicates with the main application thread through synchronisation.

When the application is closing down, it sends a dummy pipe message which the thread handles and terminates.

  • Like 2
  • Thanks 1

Share this post


Link to post
4 hours ago, David Hoyle said:

The named pipe sits in a thread and when triggered communicates with the main application thread through synchronisation.

When the application is closing down, it sends a dummy pipe message which the thread handles and terminates.

I'd be interested if it fires up fast enough for double clicking on a taskbar shortcut on a slow VM.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×