Konsolenanwendung nur einmal starten und darauf zugreifen



  • Guten Tag zusammen.
    Da ich bisher nicht wirklich fündig geworden bin hoffe ich hier ein paar Anstösse zu finden.
    Ich muss für meinen AG eine Konsolenanwendung (in C/C++) schreiben die einen gewissen UDP-Port ausliest und dann dementsprechend eine WindowsMessage schickt.
    Das auslesen hätte ich schon, nun zum Problem:

    Die Anwendung wird aus einem Programm mit Startparametern gestartet.
    Falls bereits eine Instanz dieser (meiner) Anwendung existiert sollen Variablen dieser Instanz verändert werden (Array von WindowHanldes) und eine neue Instanz gar nicht erst zum laufen kommen.
    Das ganze aus der "rufenden" Anwendung zu steuern, ob man startet oder nicht usw, ist nicht möglich.

    Ist das überhaupt (in C/C++) so möglich?
    Im Grunde brauch ich also 2 Infos:
    1. Wie kann ich mehrfachaufrufe der Anwenung vehindern
    2. Kann ich beim erneuten Aufruf Variablen der bereits laufendn Instanz ändern (und wie)?

    Ich hoffe es ist soweit verständlich geschrieben und hoffe ihr könnt mir ein wenig auf die Sprünge helfen.

    Vielen Dank!



  • Mit ANSI C ist eine Mehrfachinstanziierung nicht erkennbar, dazu sind Betriebssystemspezifiken nötig.
    Da du mit Windows arbeitest, sollte die Frage dorthin. Die erzählen dir dann das Notwendige zu Mutexen und dergleichen.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • 1. Ja
    2. Nein



  • 1. Ja
    2. Nein

    zu 1: Also das ich die laufenden Anwendungen wohl abfangen kann ist klar - nur wie war die Frage.

    zu 2: Es gibt keine Möglichkeit dann mit der aktuellen Anwendung zu kommunizieren?
    Das kann ich ja beim besten Willen nicht glauben.

    Welchen Lösungsansatz sollte ich dann verfolgen?

    Verzeiht meine Unwissenheit aber C# ist da doch etwas gnädiger was solche Aktionen angeht.



  • Die Möglichkeiten zum Erkennen der laufenden Anwendung und zur Kommunikation sind die gleichen wie in C#. Das .Net-Framework stellt nur einen Wrapper um die WINAPI-Calls bereit.



  • Du kannst nicht verhindern dass eine neue Instanz gestartet wird.

    Du kannst aber erkennen, dass bereits eine Instanz läuft, dann die Parameter an die bereits laufende Instanz übergeben, und die neue Instanz danach gleich wieder beenden.

    Zum Erkennen ob bereits eine Instanz läuft gibt es viele Wege. Wenn sonst nichts gemacht werden muss, ist wohl der üblichste, eine "named mutex" anzulegen (-> CreateMutex), und dann mit WaitForSingleObject zu checken ob man sie in Null-Zeit locken kann. Wenn ja ist man die erste Instanz, und lässt die Mutex gelockt. Wenn nein läuft schon eine andere Instanz.

    So weit, so schlecht, denn das reicht ja für dich nicht.
    Du musst irgendwie noch die Parameter an die andere Instanz übergeben.

    Dazu könntest du z.B. einen Named-Pipe-Server oder einen Mailslot verwenden.
    Dabei bekommst du die Info ob bereits eine Instanz läuft quasi "gratis" - wenn du die Named-Pipe bzw. den Mailslot nicht anlegen kannst, dann läuft schon eine Instanz.

    Die neuen Parameter musst du dabei irgendwie serialisieren, d.h. in eine "Byte-Wurst" (BLOB, Byte-Stream - wie auch immer man es nennen will) verwandeln. Sollte bei einem Haufen Window-Handles kein Problem sein.

    Diese Byte-Wurst kannst du dann über die Named-Pipe bzw. den Mailslot an die laufende Instanz schicken. Diese muss die Daten da rauslesen, und die neuen Parameter übernehmen.

    Im Prinzip alles recht einfach, der schwierigste Teil dürfte sein im Server mitzubekommen dass neue Daten eingetroffen sind. Dazu brauchst du einen Thread, oder du musst asynchrone IO Funktionen verwenden. Wenn man noch nie damit gearbeitet hat kann das äusserst lästig sein.

    Theoretisch könntest du auch gleich über UDP kommunizieren. An Stelle der Named-Pipe tritt dann ein auf einen bestimmten Port gebundener UDP Socket. Das Binden auf einen Port ist ja ebenfalls nur möglich, wenn nicht schon ein anderen Socket auf diesen Port gebunden ist (z.B. ein Socket eines anderen Prozesses, z.B. der bereits laufenden Instanz). Ich würde allerdings etwas vorziehen was einen etwas aussagekräftigeren Namen hat, wie z.B. eben Named-Pipes oder Mailslots.
    (EDIT: Wobei... kann es sein dass ich mich da jetzt täusche? Können vielleicht doch mehrere Prozesse nen Socket auf den selben UDP Port binden? Gibt ja nicht wirklich nen absoluten KO Grund warum das nicht gehen sollte... ausgenommen mal Security-Geschichten /EDIT)

    EDIT2: rofl. bin doof. entfernt. /EDIT


Log in to reply