![]() |
Doppelten Start eines Programmes verhindern
hi,
ich entwickle gerade eine applikation bei der ich nicht möchte das sie an einem rechner mehrmals gestartet werden kann... hier im forum hab ich folgende unit gefunden
Delphi-Quellcode:
so etwas ähnliches möchte ich jetzt auch in meinem programm einbinden...
unit NichtDoppeltStarten;
interface implementation uses windows,Dialogs,sysutils; var mHandle: THandle; // Mutexhandle Initialization mHandle := CreateMutex(nil,True,'xxxxx'); // 'xxxxx' Der Anwendungsname ist hier einzutragen if GetLastError = ERROR_ALREADY_EXISTS then begin // Anwendung läuft bereits {showMessage('Anwendung läuft bereits!!!!!');} // Wenn du deine Meldung willst, mach die Klammern weg Halt; end; finalization // ... und Schluß if mHandle <> 0 then CloseHandle(mHandle) end. {Dieter Hirt} und zwar soll die abfrage ob das programm schon läuft so früh wie möglich erfolgen!!! an welcher stelle muss ich da dann die abfragen einbauen??? im oncreate ereigniss meiner hauptform??? oder gehts noch früher??? |
Re: Doppelten Start eines Programmes verhindern
Steht doch da: ShowMessage(...), istnur auskommentiert.
|
Re: Doppelten Start eines Programmes verhindern
hi Andidreas,
pack deinen Quellcode in deine Projekt-Datei (*.dpr), noch bevor TMainForm (dein Hauptformular) erstellt wird... |
Re: Doppelten Start eines Programmes verhindern
Zitat:
Delphi-Quellcode:
vorbei und durchläuft das Coding
unit NichtDoppeltStarten;
Delphi-Quellcode:
automatisch. Das
Initialization
mHandle := CreateMutex(nil,True,'xxxxx'); // 'xxxxx' Der Anwendungsname ist hier einzutragen if GetLastError = ERROR_ALREADY_EXISTS then begin // Anwendung läuft bereits {showMessage('Anwendung läuft bereits!!!!!');} // Wenn du deine Meldung willst, mach die Klammern weg Halt; end;
Delphi-Quellcode:
sorgt dafür, das der Rest nicht mehr ausgeführt wird. Damit brauchst Du das Coding nirgendwo sonst aufzurufen (OnCreate o.ä.).
Halt;
Bitte noch das 'xxxxx' anpassen in einem möglichst unique-Namen Deines Programmes. Gruß, Christoph |
Re: Doppelten Start eines Programmes verhindern
Wäre es nicht besser, beim 2. Startversuch des Programmes zu dem bereits gestarteten zurückzukehren ? Genau an die Stelle, wo man in der ersten Instanz auch war ? Ich benutze dafür z.B. eine Semaphore und darüber ist hier genügend zu lesen.
P.S.: mir gefällt die Holzhammermethode mit dem halt; nicht! Das geht auch anders. |
Re: Doppelten Start eines Programmes verhindern
Hallo,
Du könntest über ![]() Ich bilde mir ein, dass ich hier ein Beispiel dazu geschrieben habe, finde es aber nicht. Eine gleichartige Lösung, die sehr gut ist, findest Du hier: ![]() Gruß Jürgen |
Re: Doppelten Start eines Programmes verhindern
Zitat:
Was aber gefällt Dir an dem Halt; nicht? Gruß, Christoph |
Re: Doppelten Start eines Programmes verhindern
Ich kenne mich da jetzt nicht 100%ig aus, aber es sollte doch auch ohne "Halt;" laufen indem du einfach überprüfst, OB es die 1. Instanz ist?
Delphi-Quellcode:
[delphi]-Tags vergessen :D
begin
if firstInstanz then begin ... Application.CreateForm(...); ... Application.Run; ... end; end; |
Re: Doppelten Start eines Programmes verhindern
Zitat:
Gruß, Christoph |
Re: Doppelten Start eines Programmes verhindern
Eine Funktion die einen Boolean zurückgibt:
Delphi-Quellcode:
Ich habe mich nicht damit auseinandergesetzt... Deshalb kann es sein, dass es so nicht geht, aber wenn es so geht, dann kann man so ein Halt; / Application.Terminate; umgehen!
function firstInstanz : Boolean;
begin // Überprüfen, ob dies die 1. Instanz ist, oder eine weitere... end; Nicht getestet:
Delphi-Quellcode:
program Project1;
uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} var mHandle : THandle; begin mHandle := CreateMutex(Nil, True, 'TForm1'); if GetLastError <> ERROR_ALREADY_EXISTS then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end; if mHandle <> 0 then CloseHandle(mHandle); end. |
Re: Doppelten Start eines Programmes verhindern
Zitat:
|
Re: Doppelten Start eines Programmes verhindern
Zitat:
Das Halt kommt ja noch vor einem Application.Initialize; (bei einer VCL-Anwendung)... Gruß, Christoph |
Re: Doppelten Start eines Programmes verhindern
Zitat:
Wenn zweiteres, bitte erläutere doch mal genauer, was genau man da Windows zerschiessen könnte mit einem Halt? Danke+Gruß, Christoph |
Re: Doppelten Start eines Programmes verhindern
Zitat:
Zitat:
Mit "break;", "exit;" und "halt;" mancht man den Code schön unstrukiert... |
Re: Doppelten Start eines Programmes verhindern
Mir ist es gelungen, die Kausalität ausser Kraft zu setzen und das am roten Kasten vorbei (Antwort vor Frage). :mrgreen: Wie immer ist mein Ansatz der, Fehler zu vermeiden und nicht erst danach einzugreifen. Im konkreten Fall würde ich einfach eine Semaphore einsetzen. Versucht jemand das Programm nochmals zu starten, dann landet er genau da, wo er vorher auch war. Der Tip mit Mutex läuft ähnlich und ist wohl durch Internet mehr verbreitet worden, aber irgendwo gibt es einen wichtigen negativen Unterschied. Frag mich aber jetzt nicht, wo genau. Da die Semaphoren einwandfrei gehen, ist mir das auch egal. 8)
Uff, jetzt schlägt der Kasten doch zu. Es gibt 1000 Möglichkeiten seinen Source unstrukturiert zu machen. HALT gehört sicherlich dazu. |
Re: Doppelten Start eines Programmes verhindern
Sagen wirs mal so : wird das Programm beendet, dann ist der Speicher immer noch da. Angenommen, Du schreibst in Word einen Text und beim Rechner wird plötzlich Stecker gezogen. Was ist nun mit dem Text ? Ist der vielleicht sogar unrettbar weg ? :shock:
|
Re: Doppelten Start eines Programmes verhindern
Zitat:
Es ging mir um folgende konkrekte Frage: Eine Instanz eines Programmes läuft im Windows und erfreut sich bester Gesundheit. Jetzt startet der User eine 2. Instanz des Programmes. Wenn ich dabei das Mutex-Prinzip umsetze und z.B. in einer separaten Unit in das Projekt einbinde, dann wir das Programm beendet zwischen begin und Application.Initialize; - also bevor der Code zum initialisieren greift:
Delphi-Quellcode:
Okay ich gebe zu, das Initialization-Blöcke in anderen Units auch schon ausgeführt werden.
{$R *.res}
... begin // hier wird der Ablauf schon unterbrochen!! Application.Initialize; Application.Title := 'xxx'; Application.CreateForm(TMainForm, MainForm); Application.Run; end. Aber nun nochmal ganz genau: Welchen Nebeneffekt hat ein Halt; zu diesem Zeitpunkt des Programmstarts? Was kann z.B. Windows nicht tun, was es normalerweise tun muss, um den Prozess korrekt zu beenden? Gruß, Christoph |
Re: Doppelten Start eines Programmes verhindern
Es könnten z.B. schon Dateihandles offen sein. Wenn die nicht mehr freigegeben werden, kreigt sie niemand sonst (naja, kommt aufs Share-flag an)
|
Re: Doppelten Start eines Programmes verhindern
Nene, so war das nicht gemeint ! Mir ging es darum, ein Programm gar nicht erst zu starten, wenn es schon gestartet ist. 8) Mit Semaphoren geht das. Zumindest hier.
|
Re: Doppelten Start eines Programmes verhindern
Zitat:
naja egal :roll: also ich hab durch denn link von jürgen thomas einen beitrag von turboPASCAL gefunden... der hat ne beispiel anwendung mal gepostet in der demonstriert wurde wie man ein programm das bereits läuft und noch mals gestartet wird in den vordergrund holt... funktioniert einwandfrei, auch wenn das programm in denn tray minmiert wurde (ok es bleibt im tray, aber es wird nicht 2 mal gestartet wie zuvor) ich hab jetzt nur noch ein kleines problem mit dem text in der taskleiste... denn muss ich in der .dpr datei festhinterlegen, würde dies aber gerne variable machen!
Delphi-Quellcode:
program DPStart;
uses Forms, Windows, DPStart_main in 'DPStart_main.pas' {Main_Form}; {$R *.res} var FirstInstance : hWnd; begin FirstInstance := FindWindow('TApplication', 'hier muss ich denn text reinschreiben'); // <-- die stelle hätte ich gern variabel!!! If FirstInstance <> 0 Then Begin If IsIconic(FirstInstance) Then ShowWindow(FirstInstance, SW_RESTORE) Else SetForeGroundWindow(FirstInstance); FlashWindow(FirstInstance, True); End Else Begin Application.Title := 'hier muss ich denn text reinschreiben';´// <-- und diese auch Application.CreateForm(TMain_Form, Main_Form); Application.Run; End; end. |
Re: Doppelten Start eines Programmes verhindern
Delphi-Quellcode:
Und das wird nicht klappen, Delphi (zumindest mein D6) mekert dan rum und will das Project nicht mehr
Application.Title := 'hier muss ich denn text reinschreiben';´// <-- und diese auch
starten und oder laden. Die CreateMutex - Version ist ein wenig flexibler und sicherer. |
Re: Doppelten Start eines Programmes verhindern
Zitat:
ich hab nur das problem, das wenn das programm im tray liegt (also als symbol neben der uhr), das dann das wieder anzeigen der form nicht klappt... :pale: muss mal kucken ob ich des da noch irgendwie rauskrieg *gg* zur info ich arbeite mit cooltrayicon... |
Re: Doppelten Start eines Programmes verhindern
ok ich habs ^^
folgende zeile hab ich in turboPASCAL's code anpassen müssen
Delphi-Quellcode:
da stand vorher SW_RESTORE, und des hat er irgendwie nicht gepackt....
If IsIconic(FirstInstance) Then ShowWindow(FirstInstance, SW_SHOW)
mit SW_SHOW kriegt ers hin... nur das icon im tray wird nicht gekillt :( |
Re: Doppelten Start eines Programmes verhindern
Zitat:
In der Projekt Datei:
Delphi-Quellcode:
In einer Unit:
SetAppTitle('Ein Titel');
Delphi-Quellcode:
Und Delphi gibt Ruhe :???:
procedure SetAppTitel(const Titel:String);
begin Application.Title:=Title; end; |
Re: Doppelten Start eines Programmes verhindern
Zitat:
In diesem Fall mag HALT funktionieren. Allerdings ist das obergrauenvoller Programmierstil und genau deswegen hab ich auch bei jedem HALT Bauchschmerzen. Wenn man ein Programm abbricht, dann sollte es ordnungsgemäß beendet werden. Windows alle Aufräumarbeiten zu überlassen ist was für Scriptkiddies, die es nicht besser wissen. Wir wissen doch alle, daß dies nie in 100% aller Fälle funktioniert. "Nach mir die Sinnflut" trifft das recht gut. |
Re: Doppelten Start eines Programmes verhindern
Wieso werde ich in Verbindung mit "HALT" gebracht ? Wer verwendet denn so was ? :warn: Wenn schon, dann gleich mit GOTO. :mrgreen:
Es gibt zwei grundsätzliche Methoden, ein Programm nur einmal zu starten. Entweder beim Starten der zweiten Instanz eines Programmes die erste zu beenden und das eben wieder zu starten, egal wo das zuerst gestartete gerade war. Das hat meistens schwerwiegende Konsequenzen. Holzhammermethoden. 8) Das wäre wirklich "nach mir die Sintflut" mit HALT etc. Die andere ist : Semaphore setzen, wie von mir vorgeschlagen, um eben genau wieder da zu sein, wo der irgendwann zu bearbeitende Text oder sonstwas, der 5 Stunden vergessen wurde eben ist. Und zwar so ungefähr :
Delphi-Quellcode:
Vielleicht geht das mit Mutex auch. Kann allerdings aus eigener Erfahrung nur sagen, dass es mit Semaphoren genau so geht. Sehr viele Fragen und Hinweisversuche in zig Foren über Mutex, die diesem ca. 80 % "Fragen-Marktanteil" beschert haben geben mir aber zu denken. 8)
hWndMe := FindWindow(appClass,appTitle);
// falls andere Instanz existiert : diese in Vordergrund bringen, // Programm steht dann wieder genau an der Stelle, an der es verlassen wurde if (hWndMe <> 0) then begin BringWindowToTop(hWndMe); ShowWindow(hWndMe,SW_SHOWNORMAL); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz