How to stop multiple instances

Post

Posted
Rating:
#1 (In Topic #1375)
Regular
bill-lancaster is in the usergroup ‘Regular’
 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?
Online now: No Back to the top

Post

Posted
Rating:
#2
Regular
vuott is in the usergroup ‘Regular’

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#3
Guru
BruceSteers is in the usergroup ‘Guru’
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 add DBus Quit and Activate commands and auto activate running program if attempted to run again (d08d1bd9) · Commits · Bruce Steers / gambasprocwatch · GitLab
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…

Code (gambas)

  1.   If DBus.Session.Applications.Exist("org.GambasProcWatch") Then
  2.     DBus["org.GambasProcWatch"]["/org/GambasProcWatch","org.command"].Activate()
  3.  

Or quit it…

Code (gambas)

  1.   If DBus.Session.Applications.Exist("org.GambasProcWatch") Then
  2.     DBus["org.GambasProcWatch"]["/org/GambasProcWatch","org.command"].Quit()
  3.  


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.

Code (gambas)

  1.  
  2.  Dim sRet As String
  3.  
  4.  sRet = Split(File.Load("/proc/" &/ Application.Id &/ "cmdline"), "\0", Null, True).Join(" ")  '  this programs full command line
  5.  
  6. ' exact match (pgrep -xf <cmdline>) the whole command line to process IDs
  7. ' (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)
  8.    Shell "pgrep -xf " & Shell(sRet) To sRet
  9.    If Split(sRet, "\n", Null, True).Count > 1 Then  ' is there more than one?
  10.      Message("Program already running")
  11.     Quit
  12.     Endif
  13.  
  14. [code numbers="1" param="gambas" scroll="1"]
  15.  
  16. [attachment]972[/attachment]
Online now: No Back to the top

Post

Posted
Rating:
#4
Regular
bill-lancaster is in the usergroup ‘Regular’
 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
Online now: No Back to the top

Post

Posted
Rating:
#5
Guru
BruceSteers is in the usergroup ‘Guru’

bill-lancaster said

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

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.

Just change the "Application.Name" in SingleInstance.class:_new() to the name of your choice then the Application.Name will not matter.

Code (gambas)

  1. Public Sub _new()
  2.  
  3. '  $sDBusName = "org.gambas." & Replace(Application.Name, " ", "_")
  4.   $sDBusName = "org.gambas.MyProgName"
  5.   $sDBusPath = "/" & Replace($sDBusName, ".", "/")
  6.   $sDBusInter = "org.command"
  7.  
  8.   $sArgList = Args.All.Copy()
  9.   $sArgList.Remove(0)
  10.  
  11.  
Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Guru
cogier is in the usergroup ‘Guru’
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.

Code (gambas)

  1. Public Sub Form_Open()
  2.  
  3.   Print No_Progs_Already_Running()
  4.  
  5.  
  6. Public Sub No_Progs_Already_Running() As Integer
  7.  
  8.   Dim sData As String
  9.   Dim sList As String[]
  10.   Dim iLoop, iCount As Integer
  11.  
  12.   Shell "ps -aux" To sData
  13.  
  14.   sList = Split(sData, gb.NewLine)
  15.  
  16.   For iLoop = 0 To sList.Max
  17.     If InStr(sList[iLoop], "/" & Application.Name) > 0 Then Inc iCount
  18.   Next
  19.  
  20.   Return iCount
  21.  
Online now: Yes Back to the top
1 guest and 0 members have just viewed this.