jrsoftware.org // Jordan Russell's Software


-Inno Setup







visitors since
Jan. 1998

Inno Setup Knowledge Base
Return to index

HOWTO: Detect instances running in any user session with AppMutex

Article Created: 2003-10-24 00:20 GMT by Jordan Russell
Last Updated: 2003-10-24 01:32 GMT by Jordan Russell

Under Windows XP with Fast User Switching or Windows NT/2000/2003 with Terminal Services, AppMutex by default will not find mutexes created in user sessions other than the one Setup/Uninstall is running under. This is because each user session has its own kernel namespace.

To detect mutexes created in other sessions, your application must create two mutexes: one with a Global\ prefix and the other without.

Mutexes with the Global\ prefix are accessible from any user session. A like-named mutex must also be created in the session namespace (i.e. without the Global\ prefix) in case the creation of the Global mutex failed due to security restrictions or lack of operating system support (versions of Windows NT prior to 4.0 Terminal Server Edition don't support the Global\ prefix).

Additionally, a special security descriptor must be passed in each of the CreateMutex() calls to ensure the mutex is accessible by different users.

Here is an example of how to create the two mutexes in Delphi:

procedure CreateMutexes(const MutexName: String);
{ Creates the two mutexes checked for by the installer/uninstaller to see if
  the program is still running.
  One of the mutexes is created in the global name space (which makes it
  possible to access the mutex across user sessions in Windows XP); the other
  is created in the session name space (because versions of Windows NT prior
  to 4.0 TSE don't have a global name space and don't support the 'Global\'
  prefix). }
  SECURITY_DESCRIPTOR_REVISION = 1;  { Win32 constant not defined in Delphi 3 }
  SecurityDesc: TSecurityDescriptor;
  SecurityAttr: TSecurityAttributes;
  { By default on Windows NT, 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 in Windows XP. 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;
  CreateMutex(@SecurityAttr, False, PChar(MutexName));
  CreateMutex(@SecurityAttr, False, PChar('Global\' + MutexName));



In your script, set AppMutex as follows:


Site contents Copyright © 1997-2021 Jordan Russell. All rights reserved.
Portions Copyright © 2000-2021 Martijn Laan. All rights reserved.