![]() |
CreateSemaphore
Delphi-Quellcode:
Diese Variante verwende ich derzeit, um zu verhindern, dass ein Programm doppelt gestartet werden kann. Funktioniert soweit auch sehr problemlos, nur habe ich jetzt unter XP einen Trick gefunden, wie man das umgehen kann. Und zwar gibt es unter XP beim Klick auf eine EXE auch die Option "Ausführen als ..." und wenn ich dort jeweils verschiedene Benutzer wähle, öffnet sich das Programm auch mehrmals.
var
Semaphore: THandle; begin ActivationMessage := RegisterWindowMessage(PChar(MyGUID)); Semaphore := CreateSemaphore(nil, 1, 1, PChar(MyGUID)); if (GetLastError = ERROR_ALREADY_EXISTS) then begin PostMessage(HWND_BROADCAST, ActivationMessage, 0, 0); Exit; end; Kann ich den oberen Code irgendwie so verändern, dass das Programm nicht "nur einmal" unter dem Benutzer, sondern "nur einmal" auf dem ganzen System läuft? |
Re: CreateSemaphore
Eventuell könntest du das ganze noch mit einem "FindWindow" koppeln und suchen ob es bereits eine Anwendung mit deinem Klassname gibt. Ist das der fall schickst du dem programm eine Message (welche du dir vorher definierst) und wartest ob die richtige Antwort zurück kommt (welche du natürlich auch definieren musst). Kommt keine oder eine falsche Antwort zurück weißt du dass, das Programm nicht deines ist sondern nur den gleichen Klassennamen hat.
|
Re: CreateSemaphore
Moin StuffMasterz,
probier mal aus, ob es funktioniert den Prefix Global\ noch vor den Namen zu setzen, also:
Code:
Semaphore := CreateSemaphore(nil, 1, 1, PChar([b][color=red]'Global\'+[/color][/b]MyGUID));
|
Re: CreateSemaphore
@SirThornberry
danke für den Tipp, ich werd das mal probieren @Christian das Global eintragen kann ich zwar ohne das er es kritisiert, jedoch ändert sich leider nichts. Man kann es so trotzdem noch mehrfach starten. Edit: Ich hab mal die Idee von Thornberry umgesetzt: klappt wunderbar! |
Re: CreateSemaphore
Eine andere Möglichkeit wäre noch, wenn du das mit GlobalAddAtom machen würdest. Der ganz große Nachteil an der Geschichte wäre aber, das wenn dein Programm abschmiert oder vom Benutzer abgeschossen wird, das GlobalDeleteAtom nicht ausgeführt wird. Und der Benutzer das Programm erst nach einem Neustart von Windows wieder benutzen kann.
Delphi-Quellcode:
var
MyAtom: ATOM; initialization MyAtom := GlobalFindAtom('{03D1CB1A-5C2C-4B0D-9311-F585653FF733}'); if MyAtom <> 0 then begin MessageBox(0, 'Programm läuft bereits.', nil, MB_OK or MB_ICONEXCLAMATION); MyAtom := 0; Halt(0); end else MyAtom := GlobalAddAtom('{03D1CB1A-5C2C-4B0D-9311-F585653FF733}'); finalization if MyAtom <> 0 then GlobalDeleteAtom(MyAtom); end. |
Re: CreateSemaphore
das Problem mit dem Neustart könnte man eventuell noch mit einem FindWindow koppeln. Denn ist der Wert gesetzt, FindWindow liefert aber nil, könnte man dies auf einem Absturz des Programmes theoretisch zurückführen.
|
Re: CreateSemaphore
Hab' mal versucht das mit MMF umzusetzen. Das ist dabei herausgekommen...
Delphi-Quellcode:
Ist auf jeden Fall besser als GlobalAddAtom.
const
MMFName = '{8EC74560-C6B6-44A2-B466-7027525527E0}'; var MMFHandle: THandle; LastError: DWORD; initialization MMFHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MMFName); LastError := GetLastError; if MMFHandle <> 0 then MessageBox(0, 'Diese Anwendung wird bereits ausgeführt.', nil, MB_OK or MB_ICONEXCLAMATION); if (MMFHandle = 0) and (LastError = ERROR_ACCESS_DENIED) then MessageBox(0, 'Diese Anwendung wird bereits unter einem anderem Benutzerkonto ausgeführt.', nil, MB_OK or MB_ICONEXCLAMATION); if (MMFHandle = 0) and (LastError = ERROR_FILE_NOT_FOUND) then begin MMFHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 1, MMFName); Exit; end; Halt(0); finalization if MMFHandle <> 0 then CloseHandle(MMFHandle); end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02: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