Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Doppelten Start eines Programmes verhindern (https://www.delphipraxis.net/79630-doppelten-start-eines-programmes-verhindern.html)

Andidreas 25. Okt 2006 15:59


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:
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}
so etwas ähnliches möchte ich jetzt auch in meinem programm einbinden...
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???

Luckie 25. Okt 2006 16:01

Re: Doppelten Start eines Programmes verhindern
 
Steht doch da: ShowMessage(...), istnur auskommentiert.

bigg 25. Okt 2006 16:04

Re: Doppelten Start eines Programmes verhindern
 
hi Andidreas,

pack deinen Quellcode in deine Projekt-Datei (*.dpr), noch bevor TMainForm (dein Hauptformular) erstellt wird...

pertzschc 25. Okt 2006 17:47

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von Andidreas
an welcher stelle muss ich da dann die abfragen einbauen??? im oncreate ereigniss meiner hauptform??? oder gehts noch früher???

Du musst das Coding in eine neue Unit speichern und diese Unit in Dein Projekt einbinden. Dadurch wird ein uses-Eintrag in der .dpr-Datei automatisch erzeugt. Wenn Dein Programm initialisiert wird, werden die Units des Projektes nacheinander durchlaufen und zwar werden dabei die Initialization-Abschnitte aller Units (so vorhanden) ausgeführt. In Deinem Fall kommt die Ausführung also in der Mutex-Unit
Delphi-Quellcode:
unit NichtDoppeltStarten;
vorbei und durchläuft das Coding
Delphi-Quellcode:
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;
automatisch. Das
Delphi-Quellcode:
Halt;
sorgt dafür, das der Rest nicht mehr ausgeführt wird. Damit brauchst Du das Coding nirgendwo sonst aufzurufen (OnCreate o.ä.).

Bitte noch das 'xxxxx' anpassen in einem möglichst unique-Namen Deines Programmes.

Gruß,
Christoph

Hansa 25. Okt 2006 18:08

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.

Jürgen Thomas 25. Okt 2006 18:18

Re: Doppelten Start eines Programmes verhindern
 
Hallo,

Du könntest über Hier im Forum suchenProgramm einmal starten Hinweise bekommen.

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: only_one.pas, nur 1 Instanz.

Gruß Jürgen

pertzschc 25. Okt 2006 19:07

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von Hansa
P.S.: mir gefällt die Holzhammermethode mit dem halt; nicht! Das geht auch anders.

Deinen 1. Punkt habe ich verstanden.

Was aber gefällt Dir an dem Halt; nicht?

Gruß,
Christoph

xZise 25. Okt 2006 20:04

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:
begin
  if firstInstanz then begin
    ...
    Application.CreateForm(...);
    ...
    Application.Run;
    ...
  end;
end;
[delphi]-Tags vergessen :D

pertzschc 25. Okt 2006 20:07

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von xZise
Delphi-Quellcode:
  if firstInstanz then begin

wer oder was ist "firstInstanz"?

Gruß,
Christoph

xZise 25. Okt 2006 20:37

Re: Doppelten Start eines Programmes verhindern
 
Eine Funktion die einen Boolean zurückgibt:
Delphi-Quellcode:
function firstInstanz : Boolean;
begin
  // Überprüfen, ob dies die 1. Instanz ist, oder eine weitere...
end;
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!

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.

Hansa 25. Okt 2006 20:43

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von pertzschc
Was aber gefällt Dir an dem Halt; nicht?

Ganz einfach : beim Programmstart wird eventuell eine Menge initialisiert, Dateien geöffnet usw. Und Du gehst jetzt hin und sagst lapidar : egal, nach mir die Sintflut. :mrgreen:

pertzschc 25. Okt 2006 20:43

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von xZise
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!

Nochmal die Frage an Dich: Was ist so schlimm an einem Halt; bzw. was genau spricht an Argumenten gegen eine Benutzung?
Das Halt kommt ja noch vor einem Application.Initialize; (bei einer VCL-Anwendung)...

Gruß,
Christoph

pertzschc 25. Okt 2006 20:45

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von Hansa
Ganz einfach : beim Programmstart wird eventuell eine Menge initialisiert, Dateien geöffnet usw.

Meinst Du Dinge innerhalb der Delphi-Anwendung, sprich Forms per Autocreate oder Datamodule oder meinst Du Dinge, die Windows automatisch macht, worauf man im Code der Anwendung keinen Einfluss hat?

Wenn zweiteres, bitte erläutere doch mal genauer, was genau man da Windows zerschiessen könnte mit einem Halt?

Danke+Gruß,
Christoph

xZise 25. Okt 2006 20:54

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von pertzschc
Zitat:

Zitat von xZise
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!

Nochmal die Frage an Dich: Was ist so schlimm an einem Halt; bzw. was genau spricht an Argumenten gegen eine Benutzung?
Das Halt kommt ja noch vor einem Application.Initialize; (bei einer VCL-Anwendung)...

Gruß,
Christoph

Sorry, aber ich habe nur einen Weg präsentiert, indem man das umgeht, und nie etwas direkt dazu gesagt...

Zitat:

Zitat von Hansa
P.S.: mir gefällt die Holzhammermethode mit dem halt; nicht! Das geht auch anders.

Aber wo wir gerade dabei sind :D ...
Mit "break;", "exit;" und "halt;" mancht man den Code schön unstrukiert...

Hansa 25. Okt 2006 21:00

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.

Hansa 25. Okt 2006 21:06

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:

pertzschc 25. Okt 2006 21:13

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von Hansa
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 ?

Den Vergleich verstehe ich nicht.

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:
{$R *.res}
...
begin
// hier wird der Ablauf schon unterbrochen!!
  Application.Initialize;
  Application.Title := 'xxx';
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.
Okay ich gebe zu, das Initialization-Blöcke in anderen Units auch schon ausgeführt werden.
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

DGL-luke 25. Okt 2006 21:52

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)

Hansa 25. Okt 2006 23:36

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.

Andidreas 26. Okt 2006 10:07

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von Luckie
Steht doch da: ShowMessage(...), istnur auskommentiert.

was isn das für ne antwort??? hast du meine frage überhaupt durchgelesen???

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.

turboPASCAL 26. Okt 2006 10:22

Re: Doppelten Start eines Programmes verhindern
 
Delphi-Quellcode:
Application.Title := 'hier muss ich denn text reinschreiben';´// <-- und diese auch
Und das wird nicht klappen, Delphi (zumindest mein D6) mekert dan rum und will das Project nicht mehr
starten und oder laden.

Die CreateMutex - Version ist ein wenig flexibler und sicherer.

Andidreas 27. Okt 2006 07:52

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von turboPASCAL
Delphi-Quellcode:
Application.Title := 'hier muss ich denn text reinschreiben';´// <-- und diese auch
Und das wird nicht klappen, Delphi (zumindest mein D6) mekert dan rum und will das Project nicht mehr
starten und oder laden.

Die CreateMutex - Version ist ein wenig flexibler und sicherer.

warum ist createmutex flexibler und sicherer??? also bis jetzt funktioniert deine variante einwandrei ;)

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...

Andidreas 27. Okt 2006 09:17

Re: Doppelten Start eines Programmes verhindern
 
ok ich habs ^^

folgende zeile hab ich in turboPASCAL's code anpassen müssen

Delphi-Quellcode:
If IsIconic(FirstInstance) Then ShowWindow(FirstInstance, SW_SHOW)
da stand vorher SW_RESTORE, und des hat er irgendwie nicht gepackt....
mit SW_SHOW kriegt ers hin... nur das icon im tray wird nicht gekillt :(

Sunlight7 19. Nov 2006 00:43

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Delphi-Quellcode:
Application.Title := 'hier muss ich denn text reinschreiben';´// <-- und diese auch

Und das wird nicht klappen, Delphi (zumindest mein D6) mekert dan rum und will das Project nicht mehr
starten und oder laden.
Ich hab das so:

In der Projekt Datei:
Delphi-Quellcode:
SetAppTitle('Ein Titel');
In einer Unit:
Delphi-Quellcode:
procedure SetAppTitel(const Titel:String);
begin
   Application.Title:=Title;
end;
Und Delphi gibt Ruhe :???:

Proddi 10. Feb 2007 15:51

Re: Doppelten Start eines Programmes verhindern
 
Zitat:

Zitat von pertzschc
Zitat:

Zitat von Hansa
Ganz einfach : beim Programmstart wird eventuell eine Menge initialisiert, Dateien geöffnet usw.

Meinst Du Dinge innerhalb der Delphi-Anwendung, sprich Forms per Autocreate oder Datamodule oder meinst Du Dinge, die Windows automatisch macht, worauf man im Code der Anwendung keinen Einfluss hat?

Wenn zweiteres, bitte erläutere doch mal genauer, was genau man da Windows zerschiessen könnte mit einem Halt?

Danke+Gruß,
Christoph

Ich denke, das ist eher eine Stil-Sache.
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.

Hansa 10. Feb 2007 23:46

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:
     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;
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)


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