2014-05-10 4 views

답변

4

표준 솔루션은 응용 프로그램 시작시 글로벌 mutex을 만드는 것입니다. 앱이 처음 시작되면 성공합니다. 후속 시도에서 실패하고 두 번째 인스턴스를 중지하고로드하지 못하도록하는 단서가됩니다.

Windows에서 CreateMutex function을 호출하여 뮤텍스를 만듭니다. 링크 된 문서에서 알 수 있듯이 mutex의 이름 앞에 Global\ 접두사를 붙이면 원하는 모든 터미널 서버 세션에서 해당 뮤직을 볼 수 있습니다. 반대로 접두어 Local\을 사용하면 접두어가 작성된 사용자 세션에만 표시됩니다.

int WINAPI _tWinMain(...) 
{ 
    const TCHAR szMutexName[] = TEXT("Global\\UNIQUE_NAME_FOR_YOUR_APP"); 
    HANDLE hMutex = CreateMutex(NULL,  /* use default security attributes */ 
           TRUE,  /* create an owned mutex   */ 
           szMutexName /* name of the mutex    */); 
    if (GetLastError() == ERROR_ALREADY_EXISTS) 
    { 
     // The mutex already exists, meaning an instance of the app is already running, 
     // either in this user session or another session on the same machine. 
     // 
     // Here is where you show an instructive error message to the user, 
     // and then bow out gracefully. 
     MessageBox(hInstance, 
        TEXT("Another instance of this application is already running."), 
        TEXT("Fatal Error"), 
        MB_OK | MB_ICONERROR); 
     CloseHandle(hMutex); 
     return 1; 
    } 
    else 
    { 
     assert(hMutex != NULL); 

     // Otherwise, you're the first instance, so you're good to go. 
     // Continue loading the application here. 
    } 
} 

일부는 OS가 당신을 위해 그것을 처리하기 때문에이 선택 사항입니다 주장 할 수 있지만

, 나는 항상 명시 적으로 자신을 후 청소 및 응용 프로그램이 종료 할 때 ReleaseMutexCloseHandle를 호출 옹호. 이것은 당신이 충돌하고 당신의 정리 코드를 실행할 기회를 갖지 않는 경우를 다루지는 않겠지 만 제가 언급 한 것처럼 운영 체제는 소유 프로세스가 종료 된 후에 매달려있는 뮤텍스를 정리할 것입니다.

+0

http://blogs.msdn.com/b/oldnewthing/archive/2006/06/20/639479.aspx –

+0

블로그 게시물을 읽은 것을 기억하지 않지만 내게는 분명합니다. 저는 단일 인스턴스 애플리케이션에 대한 큰 팬이 아니지만, 만약 당신이 그렇게한다면 더 좋은 방법을 생각할 수 없습니다. 관리자가 아닌 사용자가 다른 사용자가 앱을 실행하지 못하게하는 것에 대한 Raymond의 조언은 좋지만 관리자가 아닌 사용자가 처음에 앱을 시작할 수 있도록하려면 어떻게 구현할 것인지 잘 모르겠습니다. 관리자가 두 번째 인스턴스를 시작할 때 초기 인스턴스에서 충돌하는 코드를 작성해야 할 것 같습니까? –

+0

이 문맥에서'ReleaseMutex()'를 호출하지 마십시오. 대신에'CloseHandle()'을 사용하십시오. 'CreateMutex()'가'ERROR_ALREADY_EXISTS'를보고 'bInitialOwner' 매개 변수가 무시 된 경우) 코드 예제가 수행하지 않는 뮤텍스 잠금의 소유권을 획득 한 경우에만'ReleaseMutex()를 사용하십시오. 이 상황에서 소유권, 존재성에 대해 걱정할 필요가 없기 때문에'bInitialOwner' 매개 변수를 TRUE 대신 FALSE로 설정해야합니다. –

관련 문제