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/)
-   -   CreateMutex() verhält sich komisch (https://www.delphipraxis.net/204102-createmutex-verhaelt-sich-komisch.html)

Shark99 23. Apr 2020 15:18

CreateMutex() verhält sich komisch
 
Ich muss einen Bug in einer 10 Jahre alten App fixen, die seit Windows update v1909 nicht mehr korrekt funktioniert.

Man soll nur eine Instanz der Exeutable starten können.

Der alte Code der nicht mehr funktioniert schaut so aus:
Code:
  MutexHandle := CreateMutex(nil, True, 'NameOfTheApp');
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
   log('errorcode is ERROR_ALREADY_EXISTS, bring app to front');
   ...
  end else
  begin
   log('errorcode is *NOT* ERROR_ALREADY_EXISTS, app darf weiter laufen');
   ...
  end;
10 Jahre lang, wenn man die Executable zum zweiten mal startete war das MutexHandle das gleiche wie bei der ersten Instanz, und GetLastError war ERROR_ALREADY_EXISTS. Nun ist der Handle des Mutex bei jedem Start der Exe ein neuer Handle und damit kommt ERROR_ALREADY_EXISTS nie zu stande, d.h. eine zweite Instanz der Exe wird gestartet.

Weiß jemand vielleicht wieso dieses Verhalten plötzlich da ist, und was man als Alternative zum CreateMutex nehmen könnte? FindWindow kommt nicht in Frage, weil die App nicht immer mit einem Fenster startet.

Uwe Raabe 23. Apr 2020 15:44

AW: CreateMutex() verhält sich komisch
 
Versuch mal ein
Delphi-Quellcode:
'Global\' +
vor den Namen des Mutex zu setzen.

Der schöne Günther 23. Apr 2020 15:59

AW: CreateMutex() verhält sich komisch
 
Du musst dir erstmal das Handle anschauen und wenn es
Delphi-Quellcode:
Null
ist, dann
Delphi-Quellcode:
GetLastError()
prüfen.

PS: Nur weil das zurückgegebene Handle in einem 2. Prozess ein anderes ist heißt das nicht dass das darunterliegende Mutex ein anderes ist.

himitsu 23. Apr 2020 16:10

AW: CreateMutex() verhält sich komisch
 
jo, wollt ich auch grad sagen.

Delphi-Quellcode:
MutexHandle := CreateMutex(nil, True, 'Global\NameOfTheApp');
if MutexHandle <> 0 then
  if GetLastError = ERROR_ALREADY_EXISTS then
    ExistierteShon_BringToFrontAndExit
  else
    ExistierteNochNicht
else
  RaiseLastOSError;
Siehe die Dokumentation: MSDN-Library durchsuchenCreateMutex
"Return value" und die "Remarks" können auch nie schaden.

Es kann sein, dass das Verhalten bei "ohne Global/Local" geändert wurde, oder was mit Benutzerrechten oder das was dort vonwegen "guidelines outlined for Terminal Services" gesagt wurde oder ...






Bei den meisten APIs ist es so, dass man GetLastError auch nur dann auswerten darf, wenn das Result "Fehler" sagt, also z.B. bei sowas wie 0 oder -1,
aber gut, hier gibt es noch den Senderfall, dass Result<>0 und GetLastError=ERROR_ALREADY_EXISTS ist.

Denn wenn es keine Fehler gab, dann muß LastError nicht auf 0 (ERROR_SUCCESS) gesetzt werden. In diesem Fall ist das der Fehler "irgendeiner" WinAPI, die vorher aufgerufen wurde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:01 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