AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi CreateMutex läßt mehrfachstart zu...
Thema durchsuchen
Ansicht
Themen-Optionen

CreateMutex läßt mehrfachstart zu...

Ein Thema von Cyberaxx · begonnen am 1. Sep 2012 · letzter Beitrag vom 7. Dez 2016
Antwort Antwort
Benutzerbild von Cyberaxx
Cyberaxx

Registriert seit: 15. Jul 2005
311 Beiträge
 
Delphi XE5 Professional
 
#1

CreateMutex läßt mehrfachstart zu...

  Alt 1. Sep 2012, 20:06
Hallo,

mal wieder ein Problemchen und finde dazu leider keine Lösung.

Sitze gerade an einem kleinen Tool weches wenn es gestartet wird eine Übersicht anzeigt.
Wird das Programm mit Parameter /OPEN gestartet soll ein kleines Fenster aufgehen in welches man einen Namen Eintragen kann. Es soll in einer Datenbank speichern wie lange jemand telefoniert hat.

Es funktioniert ohne Parameter schon einmal sehr gut. Wird das Programm gestartet und es existiert bereits eine Instanz, so wird diese in den Vordergrung geholt.

Als Mutex hierfür verwende ich ExctractFileName(Application.ExeName) - "Callist.exe"
Wenn das Programm gestartet wird mit einem Parameter so wird als Mutex bzw sollte als Mutex "Callist.exe#CMD" erstellt werden.
Sollte nun wiederum das Programm mit dem Parameter /OPEN geöffnet werden, soll die Instanz geschlossen werden. Danach eine neue erzeugt werden.
Wird das Programm mit dem Parameter /CLOSE geöffnet so soll nur die Instanz geschlossen werden.

Da es mit dem zweiten Mutex nicht geklappt hat, habe ich ebenfalls nur "Callist.exe" als Mutex verwendet.
Die exe habe ich in ein anderes Verzeichnis kopiert und gestartet ohne parameter. Starte ich aus Delphi heraus noch einmal die exe, bekommt sie den Focus. Klappt also...
Wenn ich allerdings aus Delphi heraus mit dem Parameter /OPEN starte, wird ein neuer Mtex erstellt mit dem Namen "Callist.exe" und einfach eine neue Instanz gestartet, das verstehe ich nicht...

Delphi-Quellcode:
procedure Instance();
  var
    Mutex: THandle;
    Window: THandle;
    MutexName: string;
    WindowTime: TDateTime;
begin
  WindowTime := Now; // Start der Instanz merken
  MutexName := ExtractFileName(ParamStr(0)); // Callist.exe
  if ParamCount = 0 then begin
    Mutex := CreateMutex(nil, True, PChar(MutexName));
    if (Mutex <> 0) and (GetLastError <> ERROR_ALREADY_EXISTS) then begin
      Application.Initialize;
      Application.Title := APPLICATION_TITLE;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TMain, Main);
      Application.Run;
    end
    else begin
      Window := FindWindow(nil, APPLICATION_TITLE);
      if Window <> 0 then begin
        Windows.ShowWindow(Window, SW_Normal);
        Windows.SetForegroundWindow(Window);
      end;
    end;
  end // bis hierhin klappt alles
  else begin
    if UpperCase(ParamStr(1)) = '/OPENthen begin
      Mutex := CreateMutex(nil, True, PChar(MutexName)); // Mutex Name hat sich nicht geändert, dennoch kein Fehler...
      if (Mutex = 0) and (GetLastError = ERROR_ALREADY_EXISTS) then begin
        Window := FindWindow(nil, APPLICATION_TITLE);
        if Window <> 0 then
          SendMessage(Window, WM_CLOSE, 0, 0);
        repeat
          Sleep(200);
          Window := FindWindow(nil, APPLICATION_TITLE);
        until Window = 0;
      end;
      CreateNewCallApp;
    end
    else if UpperCase(ParamStr(1)) = '/CLOSEthen begin
      SendMessage(Window, WM_CLOSE, 0, 0);
    end;
  end;
end;

begin
  Instance();
end.
Ich weiß nicht wo da der Fehler liegt, hat jemand dazu einen Rat?
Daniel
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
  Mit Zitat antworten Zitat
Benutzerbild von Cyberaxx
Cyberaxx

Registriert seit: 15. Jul 2005
311 Beiträge
 
Delphi XE5 Professional
 
#2

AW: CreateMutex läßt mehrfachstart zu...

  Alt 1. Sep 2012, 20:25
Hm habe gerade auf MSDN gelesen das er erstellt oder geöffent wird.

Wird also wenn bereits eine Instanz läuft das Handle des Mutex immer zurück gegeben und ich muss mich nur auf den GetLastError verlassen?

Habs nun umgestellt. Dachte ich könnte mir einmal das CreateNewCallApp; sparen.
Naja so wird man schlauer.

Die frage bleibt allerdings noch offen. Kann ich mir denn immer sicher gehen so wie ichs dort habe?
Bei einem Beitrag aus der CodeLib wird ja nur auf GetLastError geprüft.
Daniel
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!

Geändert von Cyberaxx ( 1. Sep 2012 um 20:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: CreateMutex läßt mehrfachstart zu...

  Alt 1. Sep 2012, 20:44
Naja prinzipiell gibt es folgende Möglichkeiten:
  • CreateMutex schlägt fehl (Result = 0; bedingt durch fehlende Rechte, etc)
  • CreateMutex gibt ein Handle zurück und GetLastError ist <> ERROR_ALREADY_EXISTS
  • CreateMutex gibt ein Handle zurück und GetLastError ist = ERROR_ALREADY_EXISTS

Ich würde den Check auf hMutex = 0 und GetLastError = ERROR_ALREADY_EXISTS nicht in die selben Abfrage einbauen.

Delphi-Quellcode:
procedure TForm1.MutexCheck;
var
  hMutex: THandle;
begin
  hMutex := CreateMutex(nil, true, 'MutexName');
  if (hMutex = 0) then
  begin
    // kritischer Fehler beim Erzeugen / Öffnen des Mutex
  end else
  begin
    if (GetLastError = ERROR_ALREADY_EXISTS) then
    begin
      // bestehende Instanz kontaktieren
      // ist hier dein Parameter = /OPEN, brauchst du eigentlich nur die alte
      // Instanz schließen. Dadurch, dass du an dieser Stelle schon ein
      // Handle des Mutex geöffnet hast, "müsste" die aktuelle Instanz dann
      // automatisch zur "CallApp" werden.

      // an dieser Stelle könnte man wohl auch noch ein CloseHandle(hMutex)
      // einbauen, fals der Parameter NICHT /OPEN ist
    end else
    begin
      // dies ist die erste Instanz
    end;
  end;
end;
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Cyberaxx
Cyberaxx

Registriert seit: 15. Jul 2005
311 Beiträge
 
Delphi XE5 Professional
 
#4

AW: CreateMutex läßt mehrfachstart zu...

  Alt 1. Sep 2012, 21:57
Danke für die schnelle Antwort.

Ich bin bis ich danach gegoogelt habe immer davon ausgegangen das CreateMutex fehl schlägt wenn er bereits existiert, denn der Mutex kann ja nicht neu erstellt werden.
So schnell wird man schlauer
Daniel
Das Aufwachen aus einem boesen Traum muss einen nicht erleichtern. Es kann einen auch erst richtig gewahr werden lassen, was man Furchtbares getraeumt hat, vielleicht sogar welcher furchtbaren Wahrheit man im Traum begegnet ist!
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: CreateMutex läßt mehrfachstart zu...

  Alt 1. Sep 2012, 23:59
Ist mir damals mal mit Events passiert, aber denke mal bei nem Mutex wird das ähnlich ablaufen: Wenn ein UAC elevated Prozess mit Adminrechten einen Mutex mit SecurityAttributes = nil erstellt und man dann mit einem nicht elevated Prozess versucht den Mutex zu öffnen (oder neu zu erstellen), schlägt das ganze mit ERROR_ACCESS_DENIED oder sowas in der Art fehl. In dem Falle ist dann auch das Handle gleich Null.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
rothy

Registriert seit: 6. Dez 2016
1 Beiträge
 
#6

AW: CreateMutex läßt mehrfachstart zu...

  Alt 7. Dez 2016, 11:28
Im Zusammenhang mit dem Windows Gross/Kleischreibungs-Wischiwaschi bzgl.
Dateinamen bin ich gerade noch in eine andere Falle getappt.

Falls man z.B. eine Verknüfung auf ein Programm aBBa.exe hat, die Datei aber
AbbA.exe heisst, ist Application.ExeName anders wenn das Programm über
die Verküpfung gestartet wird. Das kann vermutlich auch bei Verwendung von
ParamStr(0) vorkommen.

Mutexe sind aber case-sensitiv, ...
-->
MutexName := UpperCase(MutexName); //evtuell empfehlenswert

Geändert von rothy ( 8. Dez 2016 um 09:23 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:28 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