Wie kann ich mit Purebasic feststellen, ob ein bestimmtes Linux-Programm läuft?
Mit IsProgram() kann ich ja nur Programme feststellen, die ich mit RunProgram() von Purebasic aus gestartet habe.
Ich möchte aber herausfinden ob ein anderes Programm läuft.
			
			
									
									Feststellen ob ein bestimmtest Programm läuft
- 
				stevie1401
 - Beiträge: 705
 - Registriert: 19.10.2014 15:51
 - Kontaktdaten:
 
Feststellen ob ein bestimmtest Programm läuft
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
						Linux Mint 21.x
Re: Feststellen ob ein bestimmtest Programm läuft
Hallo Stevie,
für ein Programm mit dem das eigene Programm nicht irgendwie verbandelt ist (z.B. wie ein Child-Prozess, würde aber ebenfalls funktionieren) hab ich's mal so gelöst...Hier kann der Prozess mit NAMEN gefunden werden. Dieser muss aber inkl. Groß-/Kleinschreibung passen.
Gruß, Charly
			
			
									
									für ein Programm mit dem das eigene Programm nicht irgendwie verbandelt ist (z.B. wie ein Child-Prozess, würde aber ebenfalls funktionieren) hab ich's mal so gelöst...
Code: Alles auswählen
Global.i ProgramID
Global.s ProgramOutput, NamedProcess= "firefox"
Global ProgramID = RunProgram("pidof", NamedProcess, "", #PB_Program_Open | #PB_Program_Read)
If ProgramID
	While ProgramRunning(ProgramID)
		If AvailableProgramOutput(ProgramID)
			ProgramOutput + ReadProgramString(ProgramID) + #CR$
		EndIf
	Wend
	
	CloseProgram(ProgramID)
	
	Debug "ID(s) of " + NamedProcess + " = " + ProgramOutput
	If Len(ProgramOutput)
		Debug "Instances of " + NamedProcess + ": " + Str(CountString(ProgramOutput, " ") +1)
	Else
		Debug "Instances of " + NamedProcess + ": 0"
	EndIf
EndIfGruß, Charly
PureBasic Linux-API-Library:  http://www.chabba.de
						Re: Feststellen ob ein bestimmtest Programm läuft
Habe ich für mein EventDesigner V3 benötigt.
Benötigt unter Linux noch das Paket wmctrl
			
			
									
									Benötigt unter Linux noch das Paket wmctrl
sudo apt-get install wmctrl
Code: Alles auswählen
;-TOP
; Comment : Window Functions
; Author  : mk-soft
; Version : v1.02.0
; Create  : ?
; Update  : 29.08.2020
Structure udtListWindows
  Name.s
  Class.s
  Handle.i
  Process.i
  Childs.i
  Level.i
EndStructure
Threaded NewList ListWindows.udtListWindows()
CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    
    ;- Windows
    
    Procedure.s GetTitle(Handle)
      Protected Name.s
      Name.s = Space(1024)
      GetWindowText_(Handle, @Name, Len(Name))
      ProcedureReturn Left(Name, Len(Name))
    EndProcedure
    
    Procedure.s GetClassName(Handle.i)
      Protected Class.s
      Class.s = Space(1024)
      GetClassName_(Handle, @Class, Len(Class))
      ProcedureReturn Left(Class, Len(Class))
    EndProcedure
    Procedure EnumProc(Handle.i, lParam.i)
      Protected *tmp.udtListWindows
      AddElement(ListWindows())
     
      ListWindows()\Handle = Handle
      ListWindows()\Process = 0
      GetWindowThreadProcessId_(Handle, @ListWindows()\Process)
      ListWindows()\Name = GetTitle(Handle)
      ListWindows()\Class = GetClassName(Handle)
      
      If lParam
        *tmp = lParam
        *tmp\Childs + 1
        ListWindows()\Level = *tmp\Level + 1
      Else
        ListWindows()\Level = 0
      EndIf
      
      EnumChildWindows_(Handle, @EnumProc(), @ListWindows())
      
      ProcedureReturn #True
    EndProcedure
    
    Procedure GetAllWindows() ; Result = Count of Windows
      Protected r1, len
      
      ClearList(ListWindows())
      r1 = EnumWindows_(@EnumProc(), 0)
      ProcedureReturn ListSize(ListWindows())
    EndProcedure
    
    Procedure FindNamedWindow(Name.s) ; Result = Handle
      Protected cnt, len
      len = Len(Name)
      
      GetAllWindows()
      ForEach ListWindows()
        If FindString(ListWindows()\Class, "CabinetWClass")
          Continue
        EndIf
        If FindString(ListWindows()\Class, "ShellTabWindowClass")
          Continue
        EndIf
        If Left(ListWindows()\Name, len) = Name
          ProcedureReturn ListWindows()\Handle
        EndIf
      Next
      ProcedureReturn 0
    EndProcedure
    
    Procedure CloseNamedWindow(Name.s) ; Result = Count of Windows
      Protected cnt, len
      len = Len(Name)
      GetAllWindows()
      ForEach ListWindows()
        If Left(ListWindows()\Name, len) = Name
          If FindString(ListWindows()\Class, "CabinetWClass")
            Continue
          EndIf
          If FindString(ListWindows()\Class, "ShellTabWindowClass")
            Continue
          EndIf
          SendMessage_(ListWindows()\Handle, #WM_CLOSE, 0, 0)
          cnt + 1
        EndIf
      Next
      ProcedureReturn cnt
    EndProcedure
    
  CompilerCase #PB_OS_MacOS
    
    ;- MacOS
    Threaded __IsMainScope
    __IsMainScope = #True
    
    Procedure GetAllWindows() ; Result = Count of Windows
      Protected RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, Pool
      
      If Not __IsMainScope
        Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
      EndIf
      
      ClearList(ListWindows())
      RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
      RunningAppsCount = CocoaMessage(0, RunningApps, "count")
      i = 0
      While i < RunningAppsCount
        RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
        AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
        AddElement(ListWindows())
        ListWindows()\Name = AppName
        ListWindows()\Handle = RunningApp
        i + 1
      Wend
      
      If Pool
        CocoaMessage(0, Pool, "release")
      EndIf
      
      ProcedureReturn i
    EndProcedure
    
    Procedure FindNamedWindow(Name.s) ; Result = RunningApp
      Protected r1, RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, cnt, Pool
      
      If Not __IsMainScope
        Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
      EndIf
      
      RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
      RunningAppsCount = CocoaMessage(0, RunningApps, "count")
      i = 0
      While i < RunningAppsCount
        RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
        AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
        If Name = AppName
          r1 = RunningApp
          Break
        EndIf
        i + 1
      Wend
      
      If Pool
        CocoaMessage(0, Pool, "release")
      EndIf
      
      ProcedureReturn r1
    EndProcedure
    
    Procedure CloseNamedWindow(Name.s) ;  ; Result = Count of Windows
      Protected RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, cnt, Pool
      
      If Not __IsMainScope
        Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
      EndIf
      
      RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
      RunningAppsCount = CocoaMessage(0, RunningApps, "count")
      i = 0
      While i < RunningAppsCount
        RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
        AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
        If Name = AppName
          CocoaMessage(0, RunningApp, "terminate")
          cnt + 1
        EndIf
        i + 1
      Wend
      
      If Pool
        CocoaMessage(0, Pool, "release")
      EndIf
      
      ProcedureReturn cnt
    EndProcedure
      
  CompilerCase #PB_OS_Linux
    
    ;- Linux
    
    ;- Install Paket 'sudo apt-get install wmctrl'
    
    Procedure GetAllWindows()
      Protected Compiler, Output.s, Temp.s, pos
      
        ClearList(ListWindows())
        Compiler = RunProgram("wmctrl", "-l -x", "", #PB_Program_Open | #PB_Program_Read)
        Output = ""
        If Compiler
          While ProgramRunning(Compiler)
            If AvailableProgramOutput(Compiler)
              Output = ReadProgramString(Compiler)
              AddElement(ListWindows())
              temp = "$" + Mid(Output, 3, 8)
              ListWindows()\Handle = Val(temp)
              temp = Mid(Output, 15)
              pos = FindString(temp, "  ")
              ListWindows()\Class = Left(temp, pos)
              temp = Trim(Mid(temp, pos))
              pos = FindString(temp, " ")
              ListWindows()\Name = Mid(temp, pos + 1)
            Else
              Delay(10)
            EndIf
          Wend
          CloseProgram(Compiler) ; Close the connection to the program
        Else
          Output = "Error - Programm konnte nicht gestartet werden!"
        EndIf
        
    EndProcedure
    
    Procedure FindNamedWindow(Name.s)
      Protected len = Len(Name)
      GetAllWindows()
      ForEach ListWindows()
        If Left(ListWindows()\Name, len) = Name
          If Not FindString(ListWindows()\Class, "nautilus", 1, #PB_String_NoCase)
            ProcedureReturn ListWindows()\Handle
          EndIf
        EndIf
      Next
      ProcedureReturn 0
    EndProcedure
    
    Procedure CloseNamedWindow(Name.s)  ; Result = #True or #False
      RunProgram("wmctrl", "-a " + Name, "")
      Delay(100)
      RunProgram("wmctrl", "-c " + Name, "")
      Delay(100)
      ProcedureReturn #True
    EndProcedure
    
CompilerEndSelect
;- Example
CompilerIf #PB_Compiler_IsMainFile
  
  Enumeration Windows
    #Main
  EndEnumeration
  
  Enumeration Gadgets
    
  EndEnumeration
  
  Enumeration Status
    #MainStatusBar
  EndEnumeration
  
  Procedure Main()
    
    If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 400, 200, "Window" , #PB_Window_SystemMenu)
      
      r1 = FindNamedWindow("PureBasic")
      Debug "Windows Handle = " + Hex(r1)
      ;CloseNamedWindow("PureBasic")
      
      ;Debug GetTitle(r1)
      
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_CloseWindow
            Break
        EndSelect
      ForEver
      
    EndIf
    
  EndProcedure : Main()
  
CompilerEndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
						Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
- NicTheQuick
 - Ein Admin
 - Beiträge: 8816
 - Registriert: 29.08.2004 20:20
 - Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
 
Re: Feststellen ob ein bestimmtest Programm läuft
Welche Informationen hast du denn von dem Linux-Programm, bei dem du prüfen willst, ob es läuft?
			
			
									
									
						- 
				stevie1401
 - Beiträge: 705
 - Registriert: 19.10.2014 15:51
 - Kontaktdaten:
 
Re: Feststellen ob ein bestimmtest Programm läuft
Ich weiss den Namen des Programms. 
Ich rufe es sogar selber auf.
Mir geht es darum, dass ich prüfen kann, ob dieses Programm noch läuft, wenn mein eigentliches Programm - warum auch immer - ungewollt beendet wurde.
Dieses Programm horcht nämlich auf einen bestimmten Port. Und so lange es das tut, kann ich mein eigentliches Programm, einen Server, nicht neu starten, da der Port dann blockiert ist.
Super!
Werde ich testen!
Vielen Dank!
			
			
									
									Ich rufe es sogar selber auf.
Mir geht es darum, dass ich prüfen kann, ob dieses Programm noch läuft, wenn mein eigentliches Programm - warum auch immer - ungewollt beendet wurde.
Dieses Programm horcht nämlich auf einen bestimmten Port. Und so lange es das tut, kann ich mein eigentliches Programm, einen Server, nicht neu starten, da der Port dann blockiert ist.
Super!
Werde ich testen!
Vielen Dank!
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
						Linux Mint 21.x
- NicTheQuick
 - Ein Admin
 - Beiträge: 8816
 - Registriert: 29.08.2004 20:20
 - Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
 
Re: Feststellen ob ein bestimmtest Programm läuft
In dem Fall könnte man auch herausfinden welches Programm den Port blockiert. Das könnte dir ja im Grunde auch helfen, oder?
Oftmals werden pid-Dateien erstellt um zu prüfen, ob bestimmte Programm noch laufen.
Das heißt ein Programm wird gestartet und die Prozess-ID wird in einer Datei gespeichert. Möchte man jetzt wissen, ob das Programm noch läuft, liest man die Prozess-ID aus der Datei aus und prüft, ob ein Prozess mit dieser ID noch läuft und falls ja, ob es der richtige ist. So prüfen viele Programme, ob eine Kopie von ihnen noch läuft oder ob ein anderes läuft.
Mit "netstat -tlnp" kannst du dir zum Beispiel alle Serverprozess anzeigen lassen, die gerade über TCP auf einem Socket lauschen. Als root siehst du auch alle Prozessnamen und -IDs, sonst nur bei den Prozessen, über die dein aktueller User die Macht hat.
Mit "lsof -a -iTCP -sTCP:LISTEN" erreichst du ähnliches, bloß wird dir hier wirklich nur angezeigt wird, was unter dem aktuellen User läuft.
Wenn du die Prozess-ID schon kennst, auf der ein Server läuft, dann kannst du so testen, ob unter der ID wirklich noch was läuft:
lsof -a -p <PID> -iTCP -sTCP:LISTEN -t
Wobei <PID> natürlich die Prozess-ID sein sollte. Wenn du als Ergebnis die selbe ID zurück kriegst, läuft da ein Server, du weißt dann nur nicht auf welchem Port der läuft, außer du machst das "-t" hinten weg. Kriegst du nichts zurück, dann läuft da auch kein Server.
			
			
									
									
						Oftmals werden pid-Dateien erstellt um zu prüfen, ob bestimmte Programm noch laufen.
Das heißt ein Programm wird gestartet und die Prozess-ID wird in einer Datei gespeichert. Möchte man jetzt wissen, ob das Programm noch läuft, liest man die Prozess-ID aus der Datei aus und prüft, ob ein Prozess mit dieser ID noch läuft und falls ja, ob es der richtige ist. So prüfen viele Programme, ob eine Kopie von ihnen noch läuft oder ob ein anderes läuft.
Mit "netstat -tlnp" kannst du dir zum Beispiel alle Serverprozess anzeigen lassen, die gerade über TCP auf einem Socket lauschen. Als root siehst du auch alle Prozessnamen und -IDs, sonst nur bei den Prozessen, über die dein aktueller User die Macht hat.
Mit "lsof -a -iTCP -sTCP:LISTEN" erreichst du ähnliches, bloß wird dir hier wirklich nur angezeigt wird, was unter dem aktuellen User läuft.
Wenn du die Prozess-ID schon kennst, auf der ein Server läuft, dann kannst du so testen, ob unter der ID wirklich noch was läuft:
lsof -a -p <PID> -iTCP -sTCP:LISTEN -t
Wobei <PID> natürlich die Prozess-ID sein sollte. Wenn du als Ergebnis die selbe ID zurück kriegst, läuft da ein Server, du weißt dann nur nicht auf welchem Port der läuft, außer du machst das "-t" hinten weg. Kriegst du nichts zurück, dann läuft da auch kein Server.