Sitzungsübergreifender Shared Memory Block
-
Hi zusammen,
ich habe folgende Anforderung:
Ein Anwendung kann sowohl als normale Desktopapplikation als auch als Windows Service laufen. Um das mehrfache Ausführen zu verhindern habe ich mir überlegt, die Anwendung durch einen shared memory Block zu identifizieren. Der shared memory Block besteht aus einer 32bit Prozess- und einer 32bit Thread-Id. Der shared memory Block ist benannt und trägt den Namen "InstanceLock".
Ich benutzeboost::interprocess::windows_shared_memory
, das intern die WINAPI und die FunktionCreateFileMapping
benutzt.Die Anwendung wird als Desktop-Anwendung gestartet:
Die Anwendung prüft, ob es einen shared memory Block mit einem bestimmten Namen gibt. Wenn das der Fall ist, liest sie die Prozess- und Thread-ID aus, und vergleicht die gelesene Prozess-Id mit ihrer eigenene Prozess-Id. Wenn die beiden unterschiedlich sind ist die Anwendung nicht Erzeuger des shared memory Blocks, damit nicht Besitzer und beendet sich.
So weit, so gut, funktioniert innerhalb der gleichen Windows-Sitzung.Jetzt wird die Anwendung als Windows Service gestartet. Laut MSDN verhält sich da
CreateFileMapping
anders, indem es dem shared memory Namen den PräfixGlobal\
voranstellt, aus "InstanceLock" wird alsoGlobal\InstanceLock
. Wenn die Anwendung als Desktop-Anwendung gestartet wird sucht sie natürlich nach "InstanceLock", findet nichts und geht dann davon aus, dass sie die einzige Instanz ist und läuft brav weiter.Naive Idee: Generell den Namen auf "Global\InstanceLock" zu ändern, damit sich Service und Desktopanwendung absprechen können. Funktioniert prima, wenn der Service den shared memory Block anlegt. Funktioniert leider nicht mehr so gut, wenn es die Desktop-Anwendung tun soll, denn die braucht jetzt Administrator-Rechte, das Aktivieren des Privilegs "SeCreateGlobal" reicht leider nicht aus.
Auch wenn die Verriegelung sitzungsübergreifend sein soll, d.h. wenn Benutzer A mit seinen Kontoinformationen die Anwendung startet wird das für Benutzer B nur dann erkannt, wenn der shared memory Block im "Global" Namespace angelegt worden ist.
Weiß jemand, wie ich die Anforderung für Adminrechte umgehen kann, damit die Anwendung Objekte im "Global" Namespace anlegen kann?
-
Ich hab nur die Antwort die du nicht hören willst: lass immer das Service laufen.