Is there a way to test if the application is already open so as to prevent a second instance from being opened?
I have two ideas, but I want to see if there is a proven method.
Idea 1:
Have a simple table in the database with a single field that is updated when the application is opened. And that when the application opens the first query is to see if the table.field is set.
Idea 2:
When the application opens it creates a file. This file is searched for during the open phase and if it exists then a second instance will not open. If it doesn’t then the application will open.
I am thinking there is a method to look at memory maybe?
As I understand it, this is only an issue on Windows as MacOS will handle this for you. In the Windows version of my app, I use the Mutex features in MBS to listen for and switch to an already running instance of my app.
macOS kind of handles this for you. A user can launch multiple instances of your app with open -n MyApp.app and you’ll get more than one. So if you really need to enforce one instance only, you’ll still want to use the Mutex.
And if the app crashes or the user kills the process, the field will not be restored nor the file deleted. Great way to prevent your app to work again.
in the event handler App.Open add the following code:
mMutex = New Mutex(App.ExecutableFile.Name)
If Not mMutex.TryEnter Then
MessageBox(“Application already running”)
Quit
End If
in the event handler App.Close add the following code to release the mutex
If mMutex <> Nil Then
mMutex.Leave
End If
//Bringing already running application to the front
dim w as new WindowsListMBS
dim i,c as integer
c=w.WindowCount-1
for i=0 to c
if w.WindowText(i) = “Name of the window title of your application” then
w.ActivateWindow(i)
end if
next
//-----------------------------------
Thank you for the shout out for mutex… I’ll try that in a bit. Just FYI… I don’t write for or use Microsoft Windows or Apple Macintosh… I am and have been a Linux guy only since 1999.
This code is a bit better, it brings all windows of your already running application to the front:
//-----------------------------------
dim w as new WindowsListMBS
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
//-----------------------------------
Var Lock As New Mutex("com.thezaz.beacon" + If(DebugBuild, ".debug", ""))
If Not Lock.TryEnter Then
#If TargetWin32
Var StartTime As Double = System.Microseconds
Var PushSocket As New IPCSocket
PushSocket.Path = Self.ApplicationSupport.Child("ipc").NativePath
PushSocket.Connect
Do Until PushSocket.IsConnected Or System.Microseconds - StartTime > 5000000
PushSocket.Poll
Loop
If PushSocket.IsConnected Then
PushSocket.Write(System.CommandLine + Encodings.UTF8.Chr(0))
Do Until PushSocket.BytesLeftToSend = 0 Or System.Microseconds - StartTime > 5000000
PushSocket.Poll
Loop
PushSocket.Close
End If
#EndIf
Quit
Return
Else
Self.mMutex = Lock
#If TargetWin32
Self.mHandoffSocket = New IPCSocket
Self.mHandoffSocket.Path = Self.ApplicationSupport.Child("ipc").NativePath
AddHandler Self.mHandoffSocket.DataAvailable, WeakAddressOf Self.mHandoffSocket_DataReceived
AddHandler Self.mHandoffSocket.Error, WeakAddressOf Self.mHandoffSocket_Error
Self.mHandoffSocket.Listen
#EndIf
End If
So basically, if it gets the mutex, listen for an IPC connection. If it doesn’t, pass the command line parameters to the running instance.
on mac, the default behavior for a variety of actions (double-clicking the app icon, dragging a file onto the app icon in the finder, double-clicking a file, and probably a few others I’m forgetting) is to use the already-running app.
On windows, many of these cases launch a second copy of the app, which is generally not what the user wanted.