Mit bereits laufenden Programm verbinden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
JakobDev
User
Beiträge: 63
Registriert: Mittwoch 17. Juli 2019, 17:20

Hallo,
ich möchte gerne, das mein Programm folgendes tut: Wenn es gestartet wurde, soll es prüfen, ob es bereits läuft. Sollte es bereits laufen, soll an Nachricht an die bereits laufende Version verschickt werden und das Programm anschließend beendet werden. Wie bekomme ich das am besten programmunabhängig hin. Hintergrund, ist das ich gerade einen Texteditor mit Tabs schreibe. Wenn der User den Texteditor mit einem Pfad als Argument starten möchte, soll einfach nur ein neuer Tab im bereits laufenden Editor geöffnet werden.
__deets__
User
Beiträge: 14535
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dazu brauchst du eine Form der Interprozesskommunikation. Und die wiederum haengt ab von deinem OS. Wenn du ohne Problem 3rd-party-Pakete benutzen kannst, wuerde ich dir nanomsg empfehlen. Damit machst du dann einen Server mit einem festen, bekannten Namen auf, der auf eingehende Nachrichten wartet (parallel zur GUI natuerlich). Wenn du den Editor mit einem Argument des zu oeffnenden Files neu startest (oder sogar immer), dann schickst du eine Nachricht an den Server. Wenn die innerhalb von wenigen Sekundenbruchteilen beantwortet wird, dann weisst du, dass dein Programm schon laeuft. Sonst machst du weiter.
Benutzeravatar
JakobDev
User
Beiträge: 63
Registriert: Mittwoch 17. Juli 2019, 17:20

Ich möchte die Abhängigkeiten zu anderen Paket so gering wie möglich halten, aber wenn es sein muss, nehme ich das externe Paket in Kauf. Gibt es dazu einen Beispielcode? Das Programm nutzt PyQt5.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast Dir ein Problem ausgesucht, wo man viele verschieden Themen kennen und anwenden muß.

Programme unter Linux können mit AF_UNIX-Sockets kommunizieren, die üblicherweise unter /run/user/$UID/<programm> angelegt werden.

Wenn also solch ein Socket existiert und sich mit ihm verbinden läßt, dann läuft das Programm und man kann mit ihm kommunizieren. Andernfalls muß man den Socket eventuell löschen und neu erzeugen, und ist dann der Server.

Unter Qt kann man mit einem QSocketNotifier dann auf Ereignisse warten. Denn die erste Instanz muß ja reagieren, wenn die zweite Instanz eine Anfrage stellt.
Benutzeravatar
JakobDev
User
Beiträge: 63
Registriert: Mittwoch 17. Juli 2019, 17:20

Das Problem ist, dass das Programm auf mehren Betriebssystemen laufen soll, auch wenn ich unter Linux entwickele. Ich bräuchte also eine Plattformübergreifende Lösung. Da es mehrere Programme gibt, die dieses Feature benutzen, sollte es doch da was geben.
__deets__
User
Beiträge: 14535
Registriert: Mittwoch 14. Oktober 2015, 14:29

Einer Möglichkeit habe ich dir genannt - nanomsg. Was stört dich daran?
Benutzeravatar
JakobDev
User
Beiträge: 63
Registriert: Mittwoch 17. Juli 2019, 17:20

Mein letzter Post war eine Antwort zu dem Post von Sirius3. Zu nanomsg wäre mir wie gesagt ein Beispiel lieb, da es mehre Python Bindings gibt und die Lib sehr umfangreich zu sein scheint und ich in Sache Netzwerke allgemein keine Erfahrung habe.
__deets__
User
Beiträge: 14535
Registriert: Mittwoch 14. Oktober 2015, 14:29

Benutzeravatar
JakobDev
User
Beiträge: 63
Registriert: Mittwoch 17. Juli 2019, 17:20

Ich hab mir das ganze jetzt mal per pip installiert, aber es sieht so aus, das im Paket nur die Python Bindings vorhanden sind und man nanomsg extra installieren muss. Das ist natürlich ein K.O. Kriterium, wenn ich das Programm veröffentlichen will. Gibt es keine Lösung, die nur mit einem pip Paket auskommt?
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Für solche Probleme gibt es eben keine plattformübergreifende Lösung. Unter Linux benutzt man Named-Sockets, unter Windows Named-Mutex und PostMessage: http://sanity-free.org/143/csharp_dotne ... ation.html

Ich kenne kein Paket, das die unterschiedlichen Methoden in einer schönen API benutzbar macht. Da bleibt Dir nur selber programmieren.
__deets__
User
Beiträge: 14535
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn man einen installer baut, kann man solche benötigten DLLs ja durchaus mitliefern. Statt KO zu gehen.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ich habe so etwas vor einer halben Ewigkeit umgesetzt, indem ich das Programm auf einen Netzwerk-Socket habe horchen lassen.
__deets__
User
Beiträge: 14535
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kann man machen, führt aber unter Windows ggf zu unschönen Dialogboxen, weil ja Netzwerk-Verkehr. Und Viren-Killers-Aktionismus. Darum haben wir das eben mit nanomsg gemacht. Obendrein ist das auch noch robuster (zb egal wann client und Server gestartet werden, etc.)
Benutzeravatar
JakobDev
User
Beiträge: 63
Registriert: Mittwoch 17. Juli 2019, 17:20

Ich habe jetzt pynng gefunden, was ohne externe Abhängigkeiten auskommt. Allerdings habe ich damit 3 Probleme: 1. Wenn ich Pair0() mit send_timeout erstelle, sendet er zwar, bricht danach allerdings nicht ab und läuft weiter, bis der Timeout vorbei ist und wirft eine exception, als ob nichts gesendet worden wäre. 2. Wenn ich mit .recv() warte, kommen Nachrichten an, die losgeschickt wurden, als das Programm noch gar nicht lief. Wie kann ich das unterbinden. 3. Das senden und empfangen dauert manchmal einige Sekunden. Wie kann ich das verkürzen?
__deets__
User
Beiträge: 14535
Registriert: Mittwoch 14. Oktober 2015, 14:29

Keine Ahnung. Ich benutze halt den Vorgaenger nanomsg, und damit habe ich zumindest Punkt 3 nie erlebt. Punkt 2 ist eine Entwurfsentscheidung, die ich persoenlich gut finde. Ggf. kann man das irgendwie einstellen, oder du umgehst das selbst indem du zB timestamps in deinen Nachrichten benutzt, und zu alte Nachrichten einfach verwirfst. Punkt 1 kann ich nicht beurteilen, ob das eine Fehlbedienung oder ein Fehler in NNG vorliegt.
Antworten