I have several gambas programmes that I display on my desktop (Kubuntu 24.04, Gambas3 v3.19.4).
For some reason I find multiple instances of a program are being opened so how can I prevent more than one instance being loaded?
How to stop multiple instances
-
- Posts: 217
- Joined: Tuesday 26th September 2017 3:17pm
- Location: NW England
Re: How to stop multiple instances
I don't know if this page can help you:
https://www.gambas-it.org/wiki/index.ph ... A0_avviato
https://www.gambas-it.org/wiki/index.ph ... A0_avviato
Europaeus sum !
Amare memorentes atque deflentes ad mortem silenter labimur.
Amare memorentes atque deflentes ad mortem silenter labimur.
- BruceSteers
- Posts: 1972
- Joined: Thursday 23rd July 2020 5:20pm
- Location: Isle of Wight
- Contact:
Re: How to stop multiple instances
You can use DBus and DBus.Unique
See attached project.
if the program is running it sends the arguments to the running process instead of launching the program again.
You can test it in a terminal by running it, then running it a second time with args
Also I have just added this exact thing to my GambasProcWatch program https://gitlab.com/bsteers4/gambasprocw ... c99338dd7b
I added a DBus Activate() and Quit() method
Now if you run GambasProcWatch a second time it activates the first one instead.
This way also gives you a way to control your programs from other programs using their interfaces, commands like Activate/ Quit / open some window / run some function / etc:)
Now from another program i can simply do this to activate GambasProcWatch...
Or quit it...
or you can simply use pgrep to check more than one instance but it is not as useful (and i think not as reliable) as using DBus.
See attached project.
if the program is running it sends the arguments to the running process instead of launching the program again.
You can test it in a terminal by running it, then running it a second time with args
Also I have just added this exact thing to my GambasProcWatch program https://gitlab.com/bsteers4/gambasprocw ... c99338dd7b
I added a DBus Activate() and Quit() method
Now if you run GambasProcWatch a second time it activates the first one instead.
This way also gives you a way to control your programs from other programs using their interfaces, commands like Activate/ Quit / open some window / run some function / etc:)
Now from another program i can simply do this to activate GambasProcWatch...
If DBus.Session.Applications.Exist("org.GambasProcWatch") Then
DBus["org.GambasProcWatch"]["/org/GambasProcWatch","org.command"].Activate()
Endif
Or quit it...
If DBus.Session.Applications.Exist("org.GambasProcWatch") Then
DBus["org.GambasProcWatch"]["/org/GambasProcWatch","org.command"].Quit()
Endif
or you can simply use pgrep to check more than one instance but it is not as useful (and i think not as reliable) as using DBus.
Dim sRet As String
sRet = Split(File.Load("/proc/" &/ Application.Id &/ "cmdline"), "\0", Null, True).Join(" ") ' this programs full command line
' exact match (pgrep -xf <cmdline>) the whole command line to process IDs
' (better to use the whole command as just the application name can give other results like the IDE or a terminal cd'd to the project directory, anything containing the project name in it's title)
Shell "pgrep -xf " & Shell(sRet) To sRet
If Split(sRet, "\n", Null, True).Count > 1 Then ' is there more than one?
Message("Program already running")
Quit
Endif
[gb]
- Attachments
-
- SingleBus-0.0.104.tar.gz
- (54.51 KiB) Downloaded 126 times
If at first you don't succeed , try doing something differently.
BruceS
BruceS
-
- Posts: 217
- Joined: Tuesday 26th September 2017 3:17pm
- Location: NW England
Re: How to stop multiple instances
Thanks for the ideas, have been fiddling with this on and off for a while now without success.
The pgrep check doesn't always work, neither does vuott's suggestion.
Can't quite get my head around the SingleBus example yet. The example works fine, if I change the name pf the project then I get an error "-1 unable to create dbus interface" because the dbBus registration(line 19) fails with error message "Cannot enable observer".
Regards
Bill
The pgrep check doesn't always work, neither does vuott's suggestion.
Can't quite get my head around the SingleBus example yet. The example works fine, if I change the name pf the project then I get an error "-1 unable to create dbus interface" because the dbBus registration(line 19) fails with error message "Cannot enable observer".
Regards
Bill
- BruceSteers
- Posts: 1972
- Joined: Thursday 23rd July 2020 5:20pm
- Location: Isle of Wight
- Contact:
Re: How to stop multiple instances
there are some chars that cannot be used in a DBus interface name (I only replace spaces for underscore) so the problem may be in what you name the application.bill-lancaster wrote: ↑Friday 10th January 2025 1:44pm Thanks for the ideas, have been fiddling with this on and off for a while now without success.
The pgrep check doesn't always work, neither does vuott's suggestion.
Can't quite get my head around the SingleBus example yet. The example works fine, if I change the name pf the project then I get an error "-1 unable to create dbus interface" because the dbBus registration(line 19) fails with error message "Cannot enable observer".
Regards
Bill
Just change the "Application.Name" in SingleInstance.class:_new() to the name of your choice then the Application.Name will not matter.
Public Sub _new()
' $sDBusName = "org.gambas." & Replace(Application.Name, " ", "_")
$sDBusName = "org.gambas.MyProgName"
$sDBusPath = "/" & Replace($sDBusName, ".", "/")
$sDBusInter = "org.command"
$sArgList = Args.All.Copy()
$sArgList.Remove(0)
End
If at first you don't succeed , try doing something differently.
BruceS
BruceS
- cogier
- Site Admin
- Posts: 1179
- Joined: Wednesday 21st September 2016 2:22pm
- Location: Guernsey, Channel Islands
Re: How to stop multiple instances
I am not up to speed with the dark art of working with DBus either. Here is a bit of code I put together that returns the number of instances of the same program running.
Public Sub Form_Open()
Print No_Progs_Already_Running()
End
Public Sub No_Progs_Already_Running() As Integer
Dim sData As String
Dim sList As String[]
Dim iLoop, iCount As Integer
Shell "ps -aux" To sData
sList = Split(sData, gb.NewLine)
For iLoop = 0 To sList.Max
If InStr(sList[iLoop], "/" & Application.Name) > 0 Then Inc iCount
Next
Return iCount
End