Entwickler-Ecke
Windows API - Applikationstart aus dem Windows Explorer; nur eine Instanz
kehrer - Mi 19.05.10 09:46
Titel: Applikationstart aus dem Windows Explorer; nur eine Instanz
Liebe Delphi-Gemeinde,
Die Registry so einzustellen, dass beim Doppelklick im Explorer auf eine Projektdatei mit bestimmer Erweiterung die zugehörige Applikation gestartet wird und dann diese Projektdatei geladen wird, ist ja einfach.
Wenn aber bereits eine Instanz dieser Applikation offen ist, wird dann aber eine zweite Instanz gestartet.
Einige Programme (natürlich nur MDI Anwendungen, die mehrere Projektdateien geöffnet haben können) verhalten sich aber so, dass keine zweite Instanz der Applikation gestartet wird, sondern die bereits laufende Applikation die neue Projektdatei öffnet.
Weiß jemand, wie geht das?
Ich verwende Delphi 6
Grüße,
Manfred
Nersgatt - Mi 19.05.10 09:55
Du könntest beim Start der Anwendung einen Mutex anlegen.
Beim Start fragst Du dann ab, ob der Mutex schon exisitert.
Ja -> Message an die Erste Instanz senden mit den entsprechenden Informaten, welche Datei geöffnet werden soll. Danach dann die 2. Instanz sofort wieder beenden.
Nein -> Mutex anlegen und die Datei öffen.
kehrer - Mi 19.05.10 10:10
Hallo Jens,
Danke für Deinen Antwort
Wie setzte ich denn am besten einen Mutex um, mit einer Semaphorvariable, oder gibts hier spezielle Biblitheken?
Wie ist bei einem Mutex,Semaphor sichgestellt, dass bei einem Absturz/Abschuss dieser Mutex wieder "freigegeben" wird?
Nersgatt - Mi 19.05.10 10:27
Du kannst das z.B. direkt im Quellcode des Projektes erledigen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| var h : Cardinal; begin h := CreateMutex(nil, true, 'testmutex'); If GetLastError = ERROR_ALREADY_EXISTS Then begin ShowMessage('Programm schon aktiv'); end else begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run;
CloseHandle(h);
end;
end. |
kehrer - Mi 19.05.10 10:36
Danke Jens, das klappt.
Jetzt muss ich nur noch für das Postmessage das Windows Handle der bereits laufenden Instanz herausfinden.
Wenn Du mir da noch helfen könntest wäre alles komplett,
Manfred
Nersgatt - Mi 19.05.10 10:38
Reicht "FindWindow" als Stichwort? :D
kehrer - Mi 19.05.10 10:56
ja, reicht eigentlich schon, nur:
1) über den Fensternamen kann ich nicht suchen, da dort auch der Name der geöffneten Projektdatei drin steht
2) über die klasse ist es auch nicht ganz sicher, ob es evtl. noch eine ganz andere application mit diesem namen existiert. (ich werde es aber so machen müssen)
3) eigentlich könnte man sich ja dann den Mutex sparen, weil der Findwindow auch alles nötige zurückliefert, oder?.
Nersgatt - Mi 19.05.10 11:02
Der Mutex ist halt ziemlich sicher, wenn Du einen eindeutigen Namen nimmst. Z.B. GUID. Damit hast schon mal die erste Sicherheit, dass Dein Programm läuft.
Wenn Du dann das richtige Fenster suchst, dann kannst Du an das Fenster z.B. eine Anfrage schicken, die das Fenster auf eine bestimmte Art beantworten muss. Es wäre schon sehr großer Zufall, wenn ein anderes Programm genauso funktionieren würde. Schick z.B. ein "WerBistDu" und antworte mit "DerKaiserVonChina". Wenn diese Antwort kommt, kannst Du 99,99999% sicher sein, dass es das richtige Fenster ist.
kehrer - Mi 19.05.10 11:05
Danke, tja da hätte ich eigentlich selber drauf kommen können.
Manfred
Tryer - Do 20.05.10 00:20
Zum Nachrichtenversand:
- RegisterWindowMessage() mit eindeutigem String (z.B. GUID) ist einer WM_USER+X vorzuziehen, da WM_USER für den Gebrauch innerhalb der Anwendung gedacht ist (Es könnte durch ein HWND_BROADCAST (nächster Tip) sonst durchaus zu Fehlfunktionen an anderer Stelle kommen. Beim Broadcast halt als Param das eigene Handle mitschicken, dann weis die ältere Instanz wem sie antworten soll.
- WM_COPYDATA ist der einzig sichere Weg um per Message Daten zu verschicken die größer sind als das was in den Parametern direkt Platz findet. Hier kümmert sich Windows um den Transport des Puffers in den Speicherbereich des anderen Prozesses.
Aber vielleicht hast Du das ja auch schon Tips an anderer Stelle entnommen.
Grüsse, Dirk
jaenicke - Do 20.05.10 07:36
Tryer hat folgendes geschrieben : |
| RegisterWindowMessage() mit eindeutigem String (z.B. GUID) ist einer WM_USER+X vorzuziehen, da WM_USER für den Gebrauch innerhalb der Anwendung gedacht ist |
Oder eben WM_APP + X, das ist für die IPC gedacht. Etwas anderes macht RegisterWindowMessage ja auch nicht, nur dass da der Bereich 0xC000 + X ist.
Martok - Do 20.05.10 10:25
Das habt ihr gesehen?
kehrer - Do 20.05.10 11:00
Vielen Dank füe Eure Hilfen,
ich verwende jetzt den SendMessage(...,WM_COPYDATA,....), klappt einwandfrei.
Grüße,
Manfred
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!