![]() |
Verhindern eine Anwendung mehrfach zu starten
Hallo zusammen,
ich habe versucht mein Programm kein weiteres Mal aufrufen zu lassen, wenn es bereits einmal im System geöffnet ist. Das habe ich folgendermaßen probiert:
Delphi-Quellcode:
aber leider funktioniert das bei der Anwendung nicht. Bei einer anderen schon. :gruebel:
doppelt := FindWindow('TApplication', PChar('meinProgramm'));
if doppelt <> 0 then begin if IsIconic(doppelt) then ShowWindow(doppelt, SW_RESTORE) else SetForegroundWindow(doppelt); end else begin // Programmstart end; Hoffe ihr könnt mir da weiterhelfen. Gruß, Moony |
Re: Verhindern eine Anwendung mehrfach zu starten
Na dann suchen wir doch einfach mal:
![]() |
Re: Verhindern eine Anwendung mehrfach zu starten
Wird das Fenster gefunden, resp ist doppelt <> 0 ?
|
Re: Verhindern eine Anwendung mehrfach zu starten
Hi,
ich hoffe mal du hast nicht einfach ohne zu überlegen nen Quelltext per Copy&Paste übernommen? Falls doch: Check mal, ob dein Application.Title wirklich 'meinProgramm' ist. Bei mir funktioniert der Code. Mfg FAlter |
Re: Verhindern eine Anwendung mehrfach zu starten
|
Re: Verhindern eine Anwendung mehrfach zu starten
@ toms:
doppelt ist immer <> 0. Egal ob die Anwendung bereits geöffnet ist oder nicht. @FAlter: Natürlich NICHT. Da steht der Title statisch drin, wie er bei den Optionen unter Application.Title angegeben ist. @fuknersascha: schaue ich mir eben an und probiere das aus. |
Re: Verhindern eine Anwendung mehrfach zu starten
Hi,
Zitat:
Mfg FAlter |
Re: Verhindern eine Anwendung mehrfach zu starten
Die Zeilen stehen in der *.dpr.
So, habe jetzt den Code con Luckie probiert und wenn ich die Anwendung zum zweiten Mal aufrufe, bekomme ich eine Exception. Ich habe jedoch diesen Code nicht als separate Unit angebunden, sondern meinen alten Source in der *.dpr ersetzt. |
Re: Verhindern eine Anwendung mehrfach zu starten
Hi,
Zitat:
Delphi-Quellcode:
Ich persönlich würde die Komponente aus der CodeLib nehmen, da steht was von Parameterübergabe dabei ;)
program Project1;
uses Windows, Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} var Doppelt: THandle; begin //Sicherstellen, dass zweiter Parameter Application.Title entspricht! //Delphi ärgert bei Verwendung einer Konstante. doppelt := FindWindow('TApplication', 'Test'); if doppelt <> 0 then begin if IsIconic(doppelt) then ShowWindow(doppelt, SW_RESTORE) else SetForegroundWindow(doppelt); end else begin Application.Initialize; Application.Title := 'Test'; Application.CreateForm(TForm1, Form1); Application.Run; end; end. Mfg FAlter |
Re: Verhindern eine Anwendung mehrfach zu starten
Noch mal: JA, es steht an der richtigen Stelle!!!!
In meinem anderen Programm funktioniert das ja. |
Re: Verhindern eine Anwendung mehrfach zu starten
Eine Alternative:
Delphi-Quellcode:
initialization
hApp := CreateMutex(nil, True, 'APPNAME'); if GetLastError = ERROR_ALREADY_EXISTS then begin MessageDlg('Das Programm kann nur einmal gestart werden!', mtError, [mbOK],0); Halt; end; finalization if hApp <> 0 then CloseHandle(hApp); Edit: Hab gerade gesehen, dass Luckie einen fast identischen Code bereits verlinkt hat. |
Re: Verhindern eine Anwendung mehrfach zu starten
Also ich habe den Code von Luckie als unit eingebunden und der Funzt bei mir schon ewig ohne Probleme
|
Re: Verhindern eine Anwendung mehrfach zu starten
Ich habe jetzt die Komponente von
![]() @Subdata: so habe ich es auch schon probiert, aber alles erfolglos. Ich bekomme jedesmal eine dicke Exception wenn ich die Applikation das zweite Mal starte. @fuknersascha: Ich habe jetzt nochmals den Code von Luckie 1:1 kopiert nur den Unitnamen umbenannt und ich bekomme beim zweiten Start des Applikation eine Exception. Bei dieser Zeile:
Delphi-Quellcode:
steht der Programmtitel statisch als String.
mHandle := CreateMutex(nil,True,'meinProgrammtitel');
|
Re: Verhindern eine Anwendung mehrfach zu starten
Da muss dein Programmtitel rein also MeinProgramm.exe
|
Re: Verhindern eine Anwendung mehrfach zu starten
Mit oder ohne Extention?
|
Re: Verhindern eine Anwendung mehrfach zu starten
Nein, da kann jede beliebige, eindeutige Zeichenfolge stehen. Am besten nimmt man eine GUID dafür.
|
Re: Verhindern eine Anwendung mehrfach zu starten
Zitat:
bekommst Du die Exception auch, wenn Du die Applikation nicht aus der IDE startest? Grüße Klaus |
Re: Verhindern eine Anwendung mehrfach zu starten
Notfalls:
Bei LMD-Tools gibt es ein "OneInstance" ... Entweder Downloaden ( ![]() |
Re: Verhindern eine Anwendung mehrfach zu starten
Zitat:
[EDIT]Da guckt man vor dem absenden mal schnell etwas nach; und was passiert? Luckie sendet 2 Minuten früher :cry: |
Re: Verhindern eine Anwendung mehrfach zu starten
Zitat:
Wie Luckie bereits erwähnte, bietet sich eine GUID an. Edit: Der Hai war schneller ;-) |
Re: Verhindern eine Anwendung mehrfach zu starten
also ich habe es bei mir mit gemacht habe es nie anders versucht habe auch mit dem Code nie Probleme gehabt
Da kommt man ja mit dem schreiben garnet hinterher |
Re: Verhindern eine Anwendung mehrfach zu starten
Noch'n Tipp:
![]() |
Re: Verhindern eine Anwendung mehrfach zu starten
@Klaus:
Die Exception kommt auch, wenn ich keinerlei Überprüfungen in die Applikation einbinde. Und wo bekomme ich diese GUI-ID her? |
Re: Verhindern eine Anwendung mehrfach zu starten
Zitat:
|
Re: Verhindern eine Anwendung mehrfach zu starten
PS: MD5 und GUID sind gleich groß ... also falls sich mal jemand eine GUID live berechnen will :angel:
Also wenn man möchte, daß eine bestimmte Datei (und nur die eine Dateiversion) nur einmal gestartet werden darf > MD5 aus sich selbst (eigene EXE) berechnen |
Re: Verhindern eine Anwendung mehrfach zu starten
So, habe das folgendermaßen gemacht:
Delphi-Quellcode:
In der *.dpr selbst steht nichts drin, was eine vorherige Überprüfung durchführt. Weiterhin bekomme ich beim zwieten Start eine Exception. Blöd, dass man so etwas nicht debuggen kann...
unit Unit1;
interface implementation uses windows,Dialogs,sysutils; var mHandle: THandle; // Mutexhandle Initialization mHandle := CreateMutex(nil,True,'{7A366489-37B0-4E63-81A0-F0BBC281614D}'); // '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} |
Re: Verhindern eine Anwendung mehrfach zu starten
Hi,
Zitat:
Mfg FAlter |
Re: Verhindern eine Anwendung mehrfach zu starten
Also:
|
Re: Verhindern eine Anwendung mehrfach zu starten
Hallo,
benenne die Unit mal um. Unit1 ist denkbar schlecht. Und dann binde sie als erste unit in der dpr ein. zu langsam ;( schau dir mal das "In den Vordergrundbringen" hier an ![]() Beitrag #14 Heiko |
Re: Verhindern eine Anwendung mehrfach zu starten
Klar, dass die Unit umbenannt wird. Wurde nur vorerst zum Test angelegt und gespeichert.
Habe mir die Funktion "EnsureSingleInstance" angeschaut. Theoretisch muß ich nicht die ganzen Überprüfungen machen. Was das eigentliche in dieser Funktion betrifft, führe ich ja bei mir aus. Sprich:
Delphi-Quellcode:
Aber leider wird das Programm immer noch nciht in den Vordergrund gesetzt.
mHandle := CreateMutex(nil,True,'{7A366489-37B0-4E63-81A0-F0BBC281614D}');
... SetForegroundWindow(mHandle); BringWindowToTop(mHandle); |
Re: Verhindern eine Anwendung mehrfach zu starten
Zitat:
wenn man sich durchgelesen hat was createMutex macht, dann versuchst Du wenn mHandle = Null ist die Aplikation mit dem Handle in den Vordergrund zu setzen. Solltest Du nicht das Handle der bereits laufenden Aplikation ermitteln und diese dann in den Vordergrund setzten? Zitat:
Klaus |
Re: Verhindern eine Anwendung mehrfach zu starten
Moin, Moin,
vielleicht kann die Suche nach einer Lösung abgekürzt werden. Ich verwende seit Jahren mit Erfolg folgende Unit...
Delphi-Quellcode:
unit rzM_OneInstanceOnly;
// Unit lediglich in das Projekt aufnehmen, danach werden mehrere Instanzen // des Programmes unterbunden; bei erneutem Aufruf wird automatisch die // erste Instanz aktiviert. interface { ----------------------------------------------------------------- } implementation { ------------------------------------------------------------ } uses Forms,SysUtils,Windows; var Mutex : THandle; MName : String; h : HWnd; initialization { ------------------------------------------------------------ } MName:=ExtractFileName(ChangeFileExt(Application.ExeName,'_MTX')); Mutex:=CreateMutex(nil,true,pchar(MName)); // Mutex anlegen if GetLastError=ERROR_ALREADY_EXISTS then begin // Fehler, Pgm schon aktiv! h:=0; // vorhandene Instanz suchen repeat h:=Windows.FindWindowEx(0,h,PChar('TApplication'),PChar(Application.Title)) until h<>Application.Handle; if h<>0 then begin // aktivieren Windows.ShowWindow(h,SW_Restore); Windows.SetForegroundWindow(h); end; halt; // und diesen zweiten Aufruf beenden! end; finalization { -------------------------------------------------------------- } ReleaseMutex(Mutex); // Mutex der ersten Instanz wieder freigeben! end. |
Re: Verhindern eine Anwendung mehrfach zu starten
@taaktaak:
Supi!!! Genau so funktioniert das auch. Vielen Dank an alle, die ihre Zellen haben anstrengen müssen. Jetzt habe ich meinen Code so, wie ich es haben möchte. Für alle, die es auch mal brauchen:
Delphi-Quellcode:
unit OneInstance;
interface implementation uses Windows, Forms; var mHandle : THandle; // Mutexhandle h : HWnd; initialization mHandle := CreateMutex(nil,True,'{7A366489-37B0-4E63-81A0-F0BBC281614D}'); if GetLastError=ERROR_ALREADY_EXISTS then begin // Fehler, Pgm schon aktiv! h := 0; // vorhandene Instanz suchen repeat h := Windows.FindWindowEx(0,h,PChar('TApplication'),PChar(Application.Title)) until h<>Application.Handle; if h<>0 then begin // aktivieren Windows.ShowWindow(h,SW_Restore); Windows.SetForegroundWindow(h); end; Halt; // und diesen zweiten Aufruf beenden! end; finalization // ... und Schluß if mHandle <> 0 then CloseHandle(mHandle) end. |
Re: Verhindern eine Anwendung mehrfach zu starten
Moin, Moin.
Schön, dass es funktioniert. Allerdings halte ich das Fragment...
Delphi-Quellcode:
für suboptimal. Warum sollte man hier eine Konstante verwenden? Gibt es nicht ein Durcheinander, wenn zwei unterschiedliche Programme - die beide diese Konstante benutzen - auf diese Art und Weise ihe Vorhandensein prüfen?
CreateMutex(nil,True,'{7A366489-37B0-4E63-81A0-F0BBC281614D}');
Ist vielleicht eine etwas theoretische Situation, aber der Aufwand, statt der Konstanten den veränderten EXE-Namen zu verwenden, ist doch marginal - oder? |
Re: Verhindern eine Anwendung mehrfach zu starten
Hi,
den EXE-Namen würde ich nicht nehmen. Was, wenn zwei Programme gleich heißen? Und eine GUID ist fast ziemlich eindeutig, denn wenn der PC ne Netzwerkkarte hat, wird diese zur GUI-Erzeugung herangezogen, und die MAC sollte eindeutig sein. Und die Uhrzeit spielt auch mit rein. Du wirst wohl nicht zweimal gleichzeitig auf deinem PC ne GUID erstellen? Wenn du also für jedes Programm ne andere GUID nimmst. Kannst ja den EXE-Namen noch zusätzlich reinnehmen und meinetwegen die Zeichen {, - und } rausnehmen, wenn du Angst hast. Mfg FAlter PS: Wie wird eine GUID berechnet, wenn der PC, auf dem sie drauf ist, keine Netzwerkkarte hat? |
Re: Verhindern eine Anwendung mehrfach zu starten
Hallo Falter,
ein interesanter Aspekt! Zugegeben! Wir sind uns doch aber einig darüber, dass eine Konstante, unter der Voraussetzung, dass das ganze eine Unit ist, die bedarfsweise unverändert eingebunden wird, nicht sinnvoll ist? //edit: Noch 'mal nachgedacht! Ich halten dann die Kombination aus ExeName und Länge der Exedatei für ausreichend. Die Wahrscheinlichkeit, dass zwei unterschiedliche Programme die gleiche Länge haben UND einen Mutex anlegen, auf den geprüft wird, dann doch für sehr, sehr unwahrscheinlich - vielleicht gibt's hier ja einen Mathematiker, der die Wahrscheinlichkeit mal ausrechnen möchte? |
Re: Verhindern eine Anwendung mehrfach zu starten
Hi,
ja, bei unverändertem Übernehmen in ein anderes Projekt ist das sehr sinnlos. So gesehen kann ich nur zustimmen. Mir persönlich gefällt übrigens das ![]() Mfg FAlter |
Re: Verhindern eine Anwendung mehrfach zu starten
Application.Exename alleine scheint mir aber nicht "sicher", denn den Namen der Anwendung kann jeder zu jeder zeit ändern.
|
Re: Verhindern eine Anwendung mehrfach zu starten
Jooo, sofort und abschließend überzeugt:
"Halt" fliegt 'raus und wird durch "Terminate" ersetzt - Danke! |
Re: Verhindern eine Anwendung mehrfach zu starten
Hmm, ist in gewisser Weise ein Argument. Obwohl das natürlich schon ein "Sabotage" der Software ist, die auch an anderen Stellen, die viel unangenehmere Auswirkungen haben können, auch Probleme schaffen könnte. Hmm, was ist denn dann die derzeit beste Lösung? Mit der GUID kann ich mich nicht so richtig anfreunden...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:22 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