One example application on a computer, how?

I try to run the application only once on the computer. My application should communicate in a web service, so itโ€™s nice to let it run more than once, currently im using Mutex with this:

MyMsg := RegisterWindowMessage('My_Unique_App_Message_Name'); Mutex := CreateMutex(nil, True, 'My_Unique_Application_Mutex_Name'); if (Mutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then exit; 

This currently works to limit 1 instance of the application for each user, but my application is used in a Windows Server environment, where more than 20 users are registered at the same time, so I need them to be executed only once on the server, I'm trying to declare that Mutex like a global mutex, but I canโ€™t do this, when I do the following code, it doesnโ€™t work at all.

  MyMsg := RegisterWindowMessage('My_Unique_App_Message_Name'); Mutex := CreateMutex(nil, True, 'Global\My_Unique_Application_Mutex_Name'); if (Mutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then begin exit 

So am I doing something wrong? is there any other reliable way not to allow the launch of the second instance of my application?

+6
source share
1 answer

By default, lpMutexAttributes = nil created mutexes are available only to the user performing this process. Mutex should be available to all users.

Null DACL Security Descriptor

Do this using a security descriptor with a zero DACL. Below is the code that I use for individual instance applications / services.

 //Creates a mutex to see if the program is already running. function IsSingleInstance(MutexName : string; KeepMutex : boolean = true):boolean; const MUTEX_GLOBAL = 'Global\'; //Prefix to explicitly create the object in the global or session namespace. Ie both client app (local user) and service (system account) var MutexHandel : THandle; SecurityDesc: TSecurityDescriptor; SecurityAttr: TSecurityAttributes; ErrCode : integer; begin // By default (lpMutexAttributes =nil) created mutexes are accessible only by // the user running the process. We need our mutexes to be accessible to all // users, so that the mutex detection can work across user sessions. // Ie both the current user account and the System (Service) account. // To do this we use a security descriptor with a null DACL. InitializeSecurityDescriptor(@SecurityDesc, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@SecurityDesc, True, nil, False); SecurityAttr.nLength:=SizeOf(SecurityAttr); SecurityAttr.lpSecurityDescriptor: =@SecurityDesc ; SecurityAttr.bInheritHandle:=False; // The mutex is created in the global name space which makes it possible to // access across user sessions. MutexHandel := CreateMutex(@SecurityAttr, True, PChar(MUTEX_GLOBAL + MutexName)); ErrCode := GetLastError; // If the function fails, the return value is 0 // 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. if {(MutexHandel = 0) or }(ErrCode = ERROR_ALREADY_EXISTS) then begin result := false; closeHandle(MutexHandel); end else begin // Mutex object has not yet been created, meaning that no previous // instance has been created. result := true; if not KeepMutex then CloseHandle(MutexHandel); end; // The Mutexhandle is not closed because we want it to exist during the // lifetime of the application. The system closes the handle automatically //when the process terminates. end; 
+9
source

All Articles