Mutex musings

A Windows document based app.
Double click on a file, the app will open it because I have registered it that way.

If the user double clicks another document, my MAC version opens a new tab in the existing instance.
On Windows, I get a second instance of the App.

I know a Mutex is ‘the’ normal answer, but it seems to present a number of issues.

1/
If the app quits abnormally, the next time someone tries to start the app, they won’t be able to. (I could look for the mutex and offer to delete it, but most users would just go ‘yeah let me in’ to any such offer, and still end up with two copies)
I can envisage a situation where I not only look for a mutex, but check the datestamp. If it is more than {n} hours old, delete it , create a new one, and continue. But that doesnt resolve issue 2…

2/
If it all works normally, the file they tried to open doesn’t get opened (instance 2 kills itself) … what I really need to happen is for instance 2 to pass the command along to instance 1 and ask it to open a new document

How do people normally try to deal with this?

I am using Mutex to detect if the first instance of the application is running, and if so I am using the IPCSocket to communicate between the second and the first instance of the application. Then the first instance does the job and the second instance quits.

That sounds complex… (I have never done it before)
Do you have an example?

An IPCsocket example is in the Xojo example folder - “Example Projects/Communication/IPCSocket.xojo_binary_project”

1 Like

Thank you. I’ll go have a play with that.

Mutexes are cleaned up automatically by the OS when a program quits, even if it quits abnormally.

Here’s an example project that implements as a custom subclass of the Application class called SingleInstanceApp. The SingleInstanceApp class behaves like a normal Application class except its OpenDocument event will be raised for both ordinary documents and also those sent over IPC from another instance.

You can copy the SingleInstanceApp class into your project and then change the App superclass from Application to SingleInstanceApp.

Your app launches, uses mutex to see that it’s already running, transfers command to open document and then quit normally.

Our NamedMutexMBS class helps for that to detect the second app.
You can define your name, e.g. domain based.

Very helpful, thank you all!
I’ll report back later when I have tried these out.
:grinning:

Just before quiting the second instance of the application, it is nice to bring all windows of the first instance to the front:

dim w as new WindowsListMBS   //to list all windows on a Windows system
dim i,c as integer
c = w.WindowCount-1
for i = 0 to c
  if w.WindowImageFileName(i).IndexOf(App.ExecutableFile.Name)>-1 AND w.WindowText(i).Length>0 AND w.WindowClassName(i)="RBWindow" then 
    w.ActivateWindow(i)
  end if
next
1 Like

I have to say, all my attempts to make this work ‘as described’ so far have failed.
Windows doesn’t (for me) clear out old lock or mutex files if the app is terminated.
This would leave the system unable to launch a fresh copy after a crash.

I havent found a way to activate first copy if someone tries to start a second copy without passing a filename.
I’ll spend a little longer on it but I’m getting very discouraged.

It is required to add to the Close event of the application:

If MyMutex <> Nil Then
  MyMutex.Leave
End If

‘Close’ doesnt happen if the app terminates abnormaly.
I am testing hard.

The second instance should quit in a standard way after sending a message to the first instance.

Do a search online for “Windows Functionality Suite” by Aaron Ballman, it has everything for this.