How to stop multiple instances

Post your Gambas programming questions here.
Post Reply
bill-lancaster
Posts: 217
Joined: Tuesday 26th September 2017 3:17pm
Location: NW England

How to stop multiple instances

Post by bill-lancaster »

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?
vuott
Posts: 307
Joined: Wednesday 5th April 2017 6:07pm
Location: European Union

Re: How to stop multiple instances

Post by vuott »

I don't know if :? this page can help you:
https://www.gambas-it.org/wiki/index.ph ... A0_avviato
Europaeus sum !

Amare memorentes atque deflentes ad mortem silenter labimur.
User avatar
BruceSteers
Posts: 1972
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: How to stop multiple instances

Post by BruceSteers »

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...
  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
bill-lancaster
Posts: 217
Joined: Tuesday 26th September 2017 3:17pm
Location: NW England

Re: How to stop multiple instances

Post by bill-lancaster »

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
User avatar
BruceSteers
Posts: 1972
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: How to stop multiple instances

Post by BruceSteers »

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
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.

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
User avatar
cogier
Site Admin
Posts: 1179
Joined: Wednesday 21st September 2016 2:22pm
Location: Guernsey, Channel Islands

Re: How to stop multiple instances

Post by cogier »

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
Post Reply