Entwickler-Ecke
Windows API - Ist Programm schon gestartet worden, prüfen?
Biarchiv - Sa 26.06.04 20:40
Titel: Ist Programm schon gestartet worden, prüfen?
Hallo,
Suche eine einfache Möglichkeit um zu prüfen ob mein Program schon
einmal gestartet wurde.
Danke
Moderiert von
tommie-lie: Topic aus Sonstiges verschoben am So 27.06.2004 um 12:58
raziel - Sa 26.06.04 20:58
Hi,
Da gibts nen kleinen Trick:
Vor dem Initialisieren der Form in der "Project.dpr" ein Mutex oder ein Semaphore erstellen und anschließend GetLastError abfragen. Leifert das ERROR_ALREADY_EXIST zurück, dann wurde das Prog schon mal gestart und du kannst die doppelt gestartet Instanz beenden.
raziel
//edit: Freigeben des Mutex/der Semaphore am Ende der Project.dpr nicht vergessen!
SebDE - Sa 26.06.04 21:23
Titel: Re: Ist Programm schon gestartet worden, prüfen?
Das macht man normalerweise mit einem mutex.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var mHandle: THandle; initialization mHandle := CreateMutex(nil,True,'ProgrammName oder was anderes zum wiedererkennen'); if GetLastError = ERROR_ALREADY_EXISTS then begin ShowMessage('Programm läuft schon!'); halt; end;
finalization if mHandle <> 0 then CloseHandle(mHandle); end. |
end. soll darauf hinweisen, dass initialisation/finalisation am Ende der Unit stehen müssen ;)
Ehm es ist dabei auch zu bedenken, dass der mutex beim Absturz des Programms nicht wieder freigegeben wird. (Aber so ist halt die gängigste & vor allem einfachste Lösung :) )
Motzi - So 27.06.04 12:51
Titel: Re: Ist Programm schon gestartet worden, prüfen?
| SebDE hat folgendes geschrieben: |
| Ehm es ist dabei auch zu bedenken, dass der mutex beim Absturz des Programms nicht wieder freigegeben wird. (Aber so ist halt die gängigste & vor allem einfachste Lösung :) ) |
Stimmt nicht ganz.. im Allgemeinen gibt Windows beim Beenden eines Programms (ganz egal wie das Prog beendet wurde) alle Kernel-Objekte frei. Nur unter Win9x kann es dabei mit Mutexen zu Problemen kommen. Deswegen sollte man auch lieber Semaphore-Objekte verwenden, denn mit denen haut das immer hin...
DelphiFreund - So 27.06.04 13:26
Was ist ein Mutex und ein Semaphore?
raziel - So 27.06.04 13:39
Das sind Kernel-Objekte die (eigentlich) dazu dienen, Threads zu synchronisieren.
Ein Mutex kann immer nur von einem Thread besessen werden. So kann verhindert werden, dass z.B. zwei Threads gleichzeitig einen Shared Data (gemeinsam genutzter Speicher-) Bereich zu beschreiben. Im Gegensatz zum Mutex, den ausschließlich ein Thread besitzen kann, kann ein Semaphore mehrere Besitzer haben. Dazu wird beim Erzeugen einer Semaphore eine Maximale Anzahl an Besitzeren übergeben. Jedesmal wenn ein Thread auf diese Semaphore zugreift, wird dieser Zähler dekrementiert (erniedrigt). Wenn er bei 0 ankommt, kann kein weiterer Thread darauf zugreifen. Gibt ein Thread sein Semaphore wieder frei wierd der Zähler wieder erhöht. Das mag dann nützlich sein, wenn Du z.B. Microsoft die Anzahl der Word-Fenster begrenzen will. Einfach jedes neue Word Fensterl eine bestimmte Semaphore erstellen lassen bisses nicht mehr weiter geht.
Quelle: Win32-SDK-Referenz
raziel
//edit: kleinere fehlerchen ausgebessert... :?
DelphiFreund - So 27.06.04 14:01
Und Semaphore werden genauso wie Mutex erstellt, oder?
raziel - So 27.06.04 14:08
naja halt bei Mutexen
CREATEMUTEX anstelle von
CREATESEMAPHORE... ;-)
Zur Syntax schau mal in die Win32-SDK-Referenz, die bei Delphi dabei ist!
> Start-Programme-Borland Delphi X-Hilfe-MS SDK-Hilfedateien-Win32-SDK-Referenz
raziel
DelphiFreund - So 01.08.04 15:16
Ich bekommen immer die Fehlermeldung: 'Undefinierter Bezeichner: CreateSemaphore'. Warum? Es muss irgendeine Kleinigkeit sein, die ich vergessen habe, aber ich komm nicht drauf. (Hab davon leider auch keine Ahnung).
raziel - So 01.08.04 15:23
Ist Windows in der uses liste? :roll:
raziel
DelphiFreund - So 01.08.04 16:54
Hier ist mal der Quelltext:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| program Project1;
uses Forms, Unit1 in 'Unit1.pas' ;
{$R *.res}
const MyGUID = '{4EA7F9F9-CCE6-48AD-A6EF-C3079215C4A6}'; var Semaphore: THandle; begin Semaphore := CreateSemaphore(nil,0,1,PCHAR(MyGUID)); if (GetLastError() = ERROR_ALREADY_EXISTS) then begin closehandle(Semaphore); end else begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end; end. |
Ist noch nicht fertig
Christian S. - So 01.08.04 17:00
Hallo!
Wie Raziel bereits sagte: Die Unit "windows" muss eingebunden werden.
MfG
Peter
DelphiFreund - So 01.08.04 17:05
Reicht es nicht wenn sie in Unit1 eingebunden ist?
Christian S. - So 01.08.04 17:11
Hm. :gruebel: Komischerweise reicht das nicht. :?
MasterT - So 01.08.04 17:14
Nein das reicht nicht. Du musst ja auch bei jedem neuen Formular, ganz gleich ob du schon andere Formulare in deiner USES Liste hast, in diesem alle Units einbinden die du in dem Formular benutzt.
Gruß
MasterT
DelphiFreund - So 01.08.04 17:15
Wie kann ich eine Funktion in Unit1 for Form1.OnCreate ausführen?
Christian S. - So 01.08.04 17:20
Neue Frage -> Neuer Thread
Christian S. - So 01.08.04 17:23
| MasterT hat folgendes geschrieben: |
| Nein das reicht nicht. Du musst ja auch bei jedem neuen Formular, ganz gleich ob du schon andere Formulare in deiner USES Liste hast, in diesem alle Units einbinden die du in dem Formular benutzt. |
Ich sollte mal wieder ausschlafen ... :-(
MasterT - So 01.08.04 18:20
garnicht!
@PeterLustig: Hab ich was verpasst?
Edit die 3te :)
Ahh habs gesehen. ^^
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!