Also das mit den Pipes habe ich jetzt implementiert. Selbst ohne Kommunikation durch die Pipes kann ich folgendes erreichen:
- Nur die Erste Instanz startet normal - nur dann ist CreateNamedPipe mit FILE_FLAG_FIRST_PIPE_INSTANCE erfolgreich - Jede weitere Instanz erkennt, dass bereits eine andere Instanz läuft und kann darauf reagieren
- Eine zweite Instanz kann die erste Instanz folgendermaßen ermitteln: Sie verbindet sich mit CreateFile mit den Parametern GENERIC_READ und OPEN_EXISTING auf die Pipe und erhält das Pipe-Handle. Damit kann sie mittels GetNamedPipeServerProcessId die Prozess-ID der ersten Instanz ermitteln
- Eine dritte Instanz braucht keine Meldung mehr ausgeben, dass bereits eine Instanz läuft, da das bereits die zweite Instanz tut. Dieser Fall könnte z.B. eintreten, wenn bereits eine Instanz hinter anderen Fenstern verborgen läuft und das Programm ungeschickt gleich mehrfach geöffnet wird. Dieser Fall wird als Nebeneffekt erkannt, wenn das Verbinden auf die bestehende Pipe nicht gelingt (weil Instanz 2 bereits verbunden ist). Das Programm kann in diesem Fall ohne weitere Handlungen beendet werden.
Offen bleibt also jetzt nur noch das In-den-Vordergrund-bringen der ersten Instanz durch die zweite Instanz. Dazu benötige ich offenbar ein Fenster-
Handle der ersten Instanz, welches ich dann an SetForegroundWindow übergeben kann. Gefunden habe ich bei einer ersten Suche die GetGUIThreadInfo Funktion (benötigt die Thread-ID, welche man mittels der Prozess-ID ermitteln können sollte), welche mir eine GUITHREADINFO structure mit dem
Handle des im Thread aktiven Windows liefert. Ist das ein guter Ansatz, oder gibt es bessere/bevorzugenswertere?
Ich sehe folgende Probleme incl. Lösungen bei meinem Ansatz:
- Der Zielprozess hat wahrscheinlich mehrere Threads. In diesem Fall würde ich alle Threads durchsuchen, bis ich einen finde, der ein aktives Fenster besitzt und dieses in den Vordergrund bringen.
- Zwischen der Ermittlung des aktiven Fensters und dem Aufruf/Umsetzung von SetForegroundWindow könnte das Fenster wieder verschwunden sein (Aufruf von Hide), falls es sich dummerweise gerade um mein "Bitte warten Sie, bis die lange Operation beendet wurde"-Fenster handelt. Ich nehme an, dass SetForegroundWindow in diesem Fall einen entsprechenden Rückgabewert liefert, damit ich den Vorgang auf einem neuen aktiven Fenster wiederholen kann.
So, jetzt habe ich euch erstmal mit aktuellen Infos versorgt und werde mittagessen gehen. Wenn bis danach keine Einwände gegen das Vorgehen gepostet wurden, werde ich die Umsetzung dann angehen
Mahlzeit!
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."