Seite 1 von 1

Prozesskomunikation >__<

Verfasst: 08.10.2004 18:16
von MVXA
Hallo !
Ist ein sehr gewagtes Thema unter Windows, ich weiß (zu mindest unter VB, ka ob es die Probleme auch in PB gibt :|)

Ich habe mir ein kleinen Server geschrieben, der komplett im Hintergrund läuft. Nun will ich aber zusätzlich ein kleines Programm schreiben, dass den Server steuert (Online/Offline, Arbeitsverzecihniss, etc.). Als erste viel mir das Arbeiten mit Mutex ein aber das ist mir irgendwie zu merkwürdig >__<(hab mich mit Mutex unter VB kurze Zeit beschäftigt und bin nicht wirklich dahinter gestiegen, kann mich gern eines anderem belehren lassen). Danach hab ich mir überlegt mit Pipelines zu arbeiten. Aber das funzt nur auf NT basierten Systemen, das ist auch nicht ganz das was ich wollte. Mit Sendmessages zu arbeiten wird daran scheitern, dass die Serverseite keine Fenster hat/haben wird.

Meine Frage nun: wie kriege ich eine geschickte Prozesskomunikation unter Windows (allen Systemen !) hin ?

Verfasst: 08.10.2004 18:28
von the_pharao
also wenn du das rad nicht neu erfinden willst, benutz sendmessage und mach das fenster einfach unsichtbar.

Verfasst: 08.10.2004 19:11
von NicTheQuick
Hier habe ich etwas für meinen PBOR, damit er erkennt, ob er schon an ist. Falls ja, wird ein String an das schon laufende Programm gesendet.

Code: Alles auswählen

#Win_Main = 0
#Win_OneInstance = 1
#ProgramName.s = "PB-Test"

Global FBOR_Msg_RunOnce.l, FBOR_OneInstance_Mutex.l
Global OneInstance_AlreadyRunning.l, Parameter.s, NewParameter.l

#FBOR_Msg_Request = 0
#FBOR_Msg_Reply = 1

FBOR_Msg_RunOnce = RegisterWindowMessage_(#ProgramName + "_Msg_RunOnce")

FBOR_OneInstance_Mutex = CreateMutex_(0, 0, #ProgramName + "_OneInstance_Mutex")
If GetLastError_() = #ERROR_ALREADY_EXISTS
  OneInstance_AlreadyRunning = #True
Else
  OneInstance_AlreadyRunning = #False
EndIf

Procedure OneInstance_IsRunning()
  ProcedureReturn OneInstance_AlreadyRunning
EndProcedure

Procedure OneInstance_End()
  ReleaseMutex_(FBOR_OneInstance_Mutex)
EndProcedure

Procedure OneInstance_Close()
  CloseHandle_(FBOR_OneInstance_Mutex)
EndProcedure

Procedure OneInstance_SendParameter(Text.s)
  Protected EventID.l, CopyData.COPYDATASTRUCT
  
  If OpenWindow(#Win_OneInstance, 0, 0, 0, 0, #PB_Window_Invisible, #ProgramName)
    PostMessage_(#HWND_BROADCAST, FBOR_Msg_RunOnce, #FBOR_Msg_Request, WindowID(#Win_OneInstance))
    
    SetTimer_(WindowID(#Win_OneInstance), 0, 5000, 0)
    
    Repeat
      EventID = WaitWindowEvent()
      
      If EventID = #WM_TIMER
        Break
        
      ElseIf EventID = FBOR_Msg_RunOnce And EventwParam() = #FBOR_Msg_Reply
        CopyData\cbData = Len(Text)
        CopyData\lpData = @Text
        
        SendMessage_(EventlParam(), #WM_COPYDATA, WindowID(#Win_OneInstance), @CopyData)
        Break
      EndIf
    ForEver
    
    CloseWindow(#Win_OneInstance)
  EndIf
EndProcedure

Procedure OneInstance_Callback(hWindow.l, Message.l, wParam.l, lParam.l)
  Protected *CopyData.COPYDATASTRUCT
  
  Result = #PB_ProcessPureBasicEvents
  
  Select Message
    Case #WM_COPYDATA
      *CopyData = lParam
      
      Parameter = PeekS(*CopyData\lpData, *CopyData\cbData)
      If Parameter <> ""
        NewParameter = #True
      EndIf
      
      Result = #True
    
    Case FBOR_Msg_RunOnce
      If wParam = #FBOR_Msg_Request
        PostMessage_(lParam, FBOR_Msg_RunOnce, #FBOR_Msg_Reply, WindowID(#Win_Main))
      EndIf
  EndSelect
  
  ProcedureReturn Result
EndProcedure

If OneInstance_IsRunning()
  OneInstance_SendParameter("Zufallszahl: " + Str(Random(1000)))
  OneInstance_Close()
  End
EndIf

NewParameter = #False

If OpenWindow(#Win_Main, 0, 0, 200, 10, #PB_Window_Invisible, "OneInstance")
  SetWindowCallback(@OneInstance_Callback())
  MessageRequester("Hauptprogramm", "Es wurde ein unsichtbares Fenster erstellt." + #LFCR$ + "Startet sie das Programm nun erneut.")
  Repeat
    WindowEvent()
    If NewParameter
      MessageRequester("Hauptprogramm", "Programm wurde erneut gestartet." + #LFCR$ + "Gesendeter String: '" + Parameter "'" + #LFCR$ + "Programm wird jetzt beendet.")
      NewParameter = #False
      End
    EndIf
    Delay(10)
  ForEver
EndIf

OneInstance_End()

Verfasst: 08.10.2004 19:43
von MVXA
Danke !