Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Doppelstart einer Anwendung (https://www.delphipraxis.net/81000-doppelstart-einer-anwendung.html)

Hador 18. Nov 2006 20:45


Doppelstart einer Anwendung
 
Hallo,

ich versuche grad den doppelstart einer Anwendung zu verhindern.
Dazu hab ich in der CodeLib einen Beitrag von Luckie gefunden.

Meine Umsetzung sieht folgendermaßen aus:
Delphi-Quellcode:
var
  mHandle: THandle;
  i: Integer;

begin
  mHandle := CreateMutex(nil, True, PAnsiChar(ParamStr(0)));
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    for i := 1 to ParamCount do
      CopyData(mHandle, ParamStr(i)); // Parameter der 1. Instanz übergeben
    Application.Terminate;
  end;
  Application.Initialize; // Ggf. Formulare erzeugen
  Application.CreateForm(TGUI, GUI);
  Application.Run;
  if mHandle <> 0 then
    CloseHandle(mHandle)
end.
Mein Problem ist nur, dass es so aus irgendeinem Grund nicht funktioniert.
Nur der Grund ist mir nicht bekannt :|
Ich hoffe also mal wieder auf euch :wink:

Sunlight7 18. Nov 2006 21:09

Re: Doppelstart einer Anwendung
 
Und was funktioniert nicht?

Übrigens: Statt Application.Terminate ein Exit; :wink:

Hador 18. Nov 2006 21:33

Re: Doppelstart einer Anwendung
 
Der Sinn dieses Codes soll sein, dass die Anwendung nicht doppelt gestartet wird.
Und genau das funktioniert nicht.

Ob Exit oder App.Terminate ist egal.

bigg 18. Nov 2006 22:03

Re: Doppelstart einer Anwendung
 
Hi,

was liefert dir mHandle, wenn deine Anwendung bereits läuft und was wenn sie nicht läuft?

Hador 18. Nov 2006 22:15

Re: Doppelstart einer Anwendung
 
Jeweils 0

Also sollte es daran liegen, aber ich weiß immer noch nicht, was faclsch ist.

Sunlight7 18. Nov 2006 22:37

Re: Doppelstart einer Anwendung
 
Das liegt daran, das Du Deinen Pfad & Dateinamen übergibst, verwende einen eindeutigen Namen, dann klappts.

Den Fehlercode von GetLastError beachten. :wink:

Edit: Und dennoch: Statt Application.Terminate ein Exit; :wink:

bigg 18. Nov 2006 22:42

Re: Doppelstart einer Anwendung
 
Ich zitiere mal das msdn:

Zitat:

Return Value

If the function succeeds, the return value is a handle to the newly created mutex object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
Was liefert GetlastError?

Sunlight7 18. Nov 2006 22:47

Re: Doppelstart einer Anwendung
 
ERROR_PATH_NOT_FOUND (3) = 'Pfad nicht gefunden'

bigg 18. Nov 2006 22:51

Re: Doppelstart einer Anwendung
 
Der Pfadname kann variieren, er sollte allerdings konstant sein, ansonsten bräuchte man das Programm nur in einen anderen Ordner kopieren und starten. Habe das ganze nicht getestet, meine Vermutung sollte dennoch stimmen.

Sunlight7 18. Nov 2006 22:59

Re: Doppelstart einer Anwendung
 
Zitat:

Zitat von Windows SDK
lpName:
Points to a null-terminated string specifying the name of the mutex object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

Tut es aber nicht, CreateMutex nimmt den Pfad erst gar nicht an, das Handle ist IMMER Null, deshalb erledigt sich die Frage schon...

Edit: Also wenn schon, dann ExtractFileName(ParamStr(0));
Aber wenn man die Exe kopiert, umbenennt und nochmal startet...

Hador 18. Nov 2006 23:08

Re: Doppelstart einer Anwendung
 
Das war auf jeden Fall schonmal ein Fehler.
So bekomme ich ein Handle.

Allerdings funktioniert es dennoch nicht.


Das mit dem kopieren/umbenennen ist übrigends, bei meiner Anwendung, egal.

Christian Seehase 18. Nov 2006 23:18

Re: Doppelstart einer Anwendung
 
Moin Lars,

das das Übertragen des Wertes nicht funktioniert, durfte wohl daran liegen, dass Du bei der Funktion CopyData das Handle des Mutex übergibst, nicht das des Hauptfensters der Anwendung, und ich vermute mal stark, dass an dieses Handle die Daten mit WM_COPYDATA geschickt werden sollen.

Als String im Mutex würde ich prinzipiell etwas eindeutiges nehmen, z.B., eine GUID (STRG+SHIFT+G in der IDE um eine zu erzeugen)
Man kann durchaus von der gleichen Stelle im Dateisystem ein Programm starten, ohne dass der Pfad gleich ist (Stichwort: SUBST)

Sunlight7 18. Nov 2006 23:24

Re: Doppelstart einer Anwendung
 
Das mit dem Pfad ist ohnehin nicht möglich, aber meine Rede, eindeutiger Name.

@Hador: Wenns weiter nicht klappt, dann zeig' mal mehr Code, damit wir hier nicht herumraten müssen. :wink:

Christian Seehase 18. Nov 2006 23:27

Re: Doppelstart einer Anwendung
 
Moin Sunlight,

Zitat:

Zitat von Sunlight7
Das mir dem Pfad ist ohnehin nicht möglich,

Warum?
Da die Länge des Strings bei CreateMutex MAX_PATH ist wäre das möglich.

Sunlight7 18. Nov 2006 23:30

Re: Doppelstart einer Anwendung
 
Moin Christian,

weil wie ich es vorhin zitiert habe, es darf kein '\' in dem Namen sein, das war der Fehler, warum das Handle immer 0 war. :wink:

Hador 18. Nov 2006 23:38

Re: Doppelstart einer Anwendung
 
Es ging mir eigentlich nur darum, dass sich die zweite Instanz des Programmes nicht schließt.

Kurz könnte man den Code daher auch so darstellen:

Delphi-Quellcode:
  mHandle := CreateMutex(nil, True, '{E46EF2D5-34C6-4FC1-A3BA-E9A49C0327B0}');
  if GetLastError = ERROR_ALREADY_EXISTS then
    Exit;
Und komischerweise hab ich grad bemerkt, dass er so auch funktioniert.
So aber nicht:

Delphi-Quellcode:
  mHandle := CreateMutex(nil, True, '{E46EF2D5-34C6-4FC1-A3BA-E9A49C0327B0}');
  ShowMessage(IntToStr(mHandle));
  if GetLastError = ERROR_ALREADY_EXISTS then
    Exit;
Ist zwar jetzt für mein Problem unerheblich (Das Showmessage kann da ja weg) aber es würde mich doch interessieren, warum es so nicht funktioniert. Schreibt ShowMessage was in LastError rein?

EDIT:
Auf jeden Fall schonmal danke für eure Antworten.

SirThornberry 18. Nov 2006 23:45

Re: Doppelstart einer Anwendung
 
ich tippe ShowMessage schreibt den Lasterror (kann sein das es nur ein success ist).

Sunlight7 18. Nov 2006 23:47

Re: Doppelstart einer Anwendung
 
Jupp, U.a. 1411 :roll:

Das nervt mich immer :roll:

Mach doch so:

Delphi-Quellcode:
mHandle := CreateMutex(nil, True, '{E46EF2D5-34C6-4FC1-A3BA-E9A49C0327B0}');
  SavedError:=GetLastError;
  ShowMessage(IntToStr(mHandle));
  if SavedError = ERROR_ALREADY_EXISTS then
    Exit;

Andidreas 19. Nov 2006 00:27

Re: Doppelstart einer Anwendung
 
die lösung in dem thread könnte für dich vielleicht auch interessant sein...

:) KLICK MICH :)

Sunlight7 19. Nov 2006 00:37

Re: Doppelstart einer Anwendung
 
Okay, nachdem ich drauf geklickt habe, weiß ich, das Du nicht mich meinst :mrgreen:

Aber so was ähnliches wie in dem anderen Thread ist auch meine Methode :???:

Hansa 19. Nov 2006 02:53

Re: Doppelstart einer Anwendung
 
Es ist immer wieder schön zu sehen, wie zugegebenermaßen kleine Code-Teile im Internet rum wandern und urplötzlich sogar (teilweise) übersetzt werden. :lol: Die Vorlage habe ich wohl auch von irgendwoher, aber auf diesen Namen einer Funktion kommt wohl kein Ami oder sonstwer : "BereitsAktiv".

Googelt mal nach "BereitsAktiv". :mrgreen:

Sunlight7 19. Nov 2006 03:10

Re: Doppelstart einer Anwendung
 
Du meinst diesen hier?!

Warum Googeln? Hier im Forum suchenBereitsAktiv tuts auch.

Hansa 19. Nov 2006 03:27

Re: Doppelstart einer Anwendung
 
Ne, Google ist besser. Da steht der angesprochene Beitrag direkt oben. :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz