...
Delphi-Quellcode:
...
PreviousHandle := Windows.FindWindow(NIL,'MyProg'); //MyProg = Form1.caption
Das ist nicht allgemeingültig, denn viele Programme haben im Titel des Hauptformulars variable Informationen (z.B. den Namen der aktuell geladenen Datei, User- oder
DB-infos etc.), d.h. Du weißt beim Programmstart nicht immer, was im Titel des Hauptformulars steht. Zudem musst Du deinen Code bei jeder Verwendung individuell anpassen.
Zum Thema 'eine Instanz und Neustart' wollte ich noch meinen Senf dazugeben:
Das Kürzeste, was ich diesbezüglich auf meinem Sperrmüll gefunden habe, ist eine
Unit, die man einfach per 'uses' einbindet und dadurch einen Mehrfachstart verhindert.
Delphi-Quellcode:
unit OneInstance;
interface
implementation
uses Windows, SysUtils;
var
hMutex: Cardinal;
initialization
hMutex := CreateMutex(
nil, True, PChar(UpperCase(ExtractFileName(ParamStr(0)))));
if GetLastError = ERROR_ALREADY_EXISTS
then Halt;
end.
Ich persönlich halte das für vollkommen ausreichend.
Mit 'Restart' wäre das diese Kleinstunit (Eben reingefrickelt):
Delphi-Quellcode:
unit OneInstance;
interface
Procedure Restart;
implementation
uses Windows, SysUtils, ShellApi;
var
hMutex: Cardinal;
Procedure Restart;
Begin
CloseHandle(hMutex);
ShellExecute(
{Application.Handle} 0, '
open', Pchar(ParamStr(0)),
nil,
nil, sw_SHOWNORMAL);
Halt;
// Brutalstmögliches Beenden der eigenen Anwendung.
End;
initialization
hMutex := CreateMutex(
nil, True, PChar(UpperCase(ExtractFileName(ParamStr(0)))));
if GetLastError = ERROR_ALREADY_EXISTS
then Halt;
end.
Allerdings starten sich meine Programme nicht neu. Ich halte das für falsch. Ein Programm hat eine bestimmte Aufgabe und wenn es sie nicht erfüllen kann, dann soll sich das Programm beenden.
Wenn ich eine 24/7-Umgebung benötige, sorge ich (z.B. durch eine BAT-Datei), das die Anwendung neu gestartet wird.
Code:
:label
MyProg.exe
goto label
So kann ich einerseits die Anwendung in einer Endlosschleife am Leben halten, andererseits die gleiche Anwendung ohne Klimmzüge laufen lassen, bis sie abschmiert. Falls sie nun ständig abschmiert, kann ich die Endlosschleife einfach unterbrechen, indem ich die Batch-Datei beende (das Fenster schließe). Mit Selbstneustart benötige ich den Taskmanager, auf den ich aber auch nicht immer Zugriff habe.
Ich will nicht sagen, das das besser ist, aber es ist -für mich- so einfacher. In kritischen Umgebungen habe ich einen Sentinel, also eine Anwendung, die im Hintergrund bestimmte Prozesse überwacht und periodisch prüft, ob diese ansprechbar oder 'abgekackt' sind, d.h. hängen. Wenn ja, wird der Prozess gekillt und die Anwendung/Prozess neu gestartet. Eine zu überwachende Anwendung kann dem Sentinel auch sagen, das sie für immer sich beenden möchte, sodaß dieser die Überwachung einstellt.
So richtig hat mir das alles nie gefallen, denn eine Anwendung sollte immer laufen können. Leider geht das nicht immer (schlechte Treiber, externe
DLL usw.)
Senfertig.