J’ai une application Windows. Je souhaite autoriser plusieurs instances pour une session utilisateur unique, mais je ne veux pas de plusieurs instances d’utilisateurs différents. En termes simples, si A se connecte à Windows, il pourra alors exécuter une application autant de fois qu’il le voudra, mais plus tard, B se connectera également. Il devra attendre que toutes les applications de A soient fermées.
Est-ce possible?
Cette exigence peut être remplie à l’aide d’un object Mutex nommé dans l’ espace de noms d’objects de kernel global. Un object mutex est créé à l’aide de la fonction CreateMutex . Voici un petit programme pour illustrer son utilisation:
int _tmain(int argc, _TCHAR* argv[]) { if ( ::CreateMutexW( NULL, FALSE, L"Global\\5BDC0675-2318-404A-96CA-DBDE9BC2F71D" ) != NULL ) { std::wcout << L"Mutex acquired. GLE = " << GetLastError() << std::endl; // Continue execution } else { std::wcout << L"Mutex not acquired. GLE = " << GetLastError() << std::endl; // Exit application } _getch(); return 0; }
La première instance d'application crée l'object mutex et GetLastError renvoie ERROR_SUCCESS
(0). Les instances suivantes acquerront une référence à l'object mutex existant et GetLastError renvoie ERROR_ALREADY_EXISTS
(183). Les instances lancées à partir d'une autre session client n'obtiendront aucune référence à l'object mutex et GetLastError renvoie ERROR_ACCESS_DENIED
(5).
Quelques notes sur la mise en œuvre:
J’ai utilisé le code précédent sous Win10 / VS 2017/64 bits
Il est faux de tester si (:: CreateMutex ..
nous devons vérifier l’erreur, alors utilisez:
BOOL checkUniqueInstance() { if (::CreateMutexW(NULL, FALSE, L"Global\\27828F4B-5FC9-40C3-9E81-6C485020538F") != NULL) { auto err = GetLastError(); if (err == 0) { return TRUE; } } CSsortingng msg; msg.Format(_T("err: %d - Mutex NOT acquired"), GetLastError()); OutputDebugSsortingng(msg); // Exit application return FALSE; }