Disallow Multiple Instance of Applications on The Same Machine (Windows Server) by Other User Sessions (Both C# and C++ solution)


The purpose is to limit the concurrent usage of a piece of software on the same machine (Physically) by other user sessions. This is to virtually limit that only 1 license can be used for one user on one machine concurrently. No more-than-one users can login to the remote Windows server and use the same piece of software at the same time (Windows server allow simultaneous logins from different users)

The simplest way is to create a mutex at the Global namespace. And we use the Win32 API CreateMutex (CreateMutexA the ansi version and CreateMutexW the Unicode version).

The following Win32 C++ native code illustrates this idea, and please do not use the GUID from the example because other people may use this string as well. Use the Create GUID tool from Visual Studio Tools.

create-guid-visual-studio-tools Disallow Multiple Instance of Applications on The Same Machine (Windows Server) by Other User Sessions (Both C# and C++ solution) c / c++ c # programming languages windows

create-guid-visual-studio-tools

1
2
3
4
5
6
7
8
9
10
11
int _tmain(int argc, _TCHAR* argv[]) {
    if ( ::CreateMutexW( NULL, FALSE, L"Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B" ) != NULL ) {
        std::wcout << L"Mutex acquired. GLE = " << GetLastError() << std::endl;
        // Continue execution
    } else {
        std::wcout << "Mutex not acquired. GLE = " << GetLastError() << std::endl;
        // Exit application
    }
    _getch();
    return 0;
}
int _tmain(int argc, _TCHAR* argv[]) {
    if ( ::CreateMutexW( NULL, FALSE, L"Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B" ) != NULL ) {
        std::wcout << L"Mutex acquired. GLE = " << GetLastError() << std::endl;
        // Continue execution
    } else {
        std::wcout << "Mutex not acquired. GLE = " << GetLastError() << std::endl;
        // Exit application
    }
    _getch();
    return 0;
}

The first parameter (structure) is usually left to NULL and the second parameter is set to false. The third parameter is the name of the mutex object. Converting to C# managed .NET code, you would need code like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Runtime.InteropServices;
public class HelloACM
{
        [StructLayout(LayoutKind.Sequential)]
        public class SECURITY_ATTRIBUTES
        {
            public int nLength;
            public int lpSecurityDescriptor;
            public int bInheritHandle;
        } 
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern int CreateMutex(SECURITY_ATTRIBUTES lpMutexAttributes, bool bInitialOwner, string lpName); 
 
        public static int Main(string[] args)
        {
            // Avoid Multiple Instances of Different Users BUT Allow Multiple Instances on Single User Session
            if (CreateMutex(null, false, "Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B") == 0)
            {
                // Multiple Instances from One Single User are Allowed.
                MessageBox.Show("The Software is already running in other sessions.");
                return -1;
            }
        }
}
using System.Runtime.InteropServices;
public class HelloACM
{
        [StructLayout(LayoutKind.Sequential)]
        public class SECURITY_ATTRIBUTES
        {
            public int nLength;
            public int lpSecurityDescriptor;
            public int bInheritHandle;
        } 
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern int CreateMutex(SECURITY_ATTRIBUTES lpMutexAttributes, bool bInitialOwner, string lpName); 

        public static int Main(string[] args)
        {
            // Avoid Multiple Instances of Different Users BUT Allow Multiple Instances on Single User Session
            if (CreateMutex(null, false, "Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B") == 0)
            {
                // Multiple Instances from One Single User are Allowed.
                MessageBox.Show("The Software is already running in other sessions.");
                return -1;
            }
        }
}

The above code still allows multiple instances for the single user session because the user may need to open two instances to copy data from one to another. This is also one way of protecting software.

References

1. StackOverflow: http://stackoverflow.com/questions/28240354/how-to-avoid-multiple-instances-of-different-users-but-allow-multiple-instances
2. CreateMutex API MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411.aspx
3. Kernel Object NameSpace MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa382954.aspx

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
562 words
Last Post: C/C++ Coding Exercise - 2025. Line Fighting - Timus Online Judge
Next Post: C# Example of Using LINQ - 1

The Permanent URL is: Disallow Multiple Instance of Applications on The Same Machine (Windows Server) by Other User Sessions (Both C# and C++ solution)

Leave a Reply