프로그래밍/델파이

CreateMutex를 이용한 다중 실행 방지 방법.

채윤아빠 2010. 4. 16. 18:47
728x90
반응형
서론
기존에 다중 실행을 방지하기 위해서 FindWindow를 이용하고 있었습니다. 하지만 문제는 타이틀이 변경되거나 하게 되면, 제대로 처리가 안되어서 CreateMutex를 이용하였었습니다. 그런데, 윈도우 세션에 상관없이 어떤 세션에서든 PC에서 서비스처럼 단 1번만 실행되어야만 하는 경우에 제대로 적용하지 못하였었습니다.

예를 들면, 현재 세션에서 프로그램을 실행시켜 놓고, 사용자 전환을 통하여 다른 세션으로 로그인 하여 동일한 프로그램을 실행하는 것이 가능하다는데 문제가 있었습니다. FindWindow로는 당연히 해결이 되지 않았고, 우연하게 알게된 ToolAPI를 사용해 보았지만, 될때도 있고 안될때도 있었습니다.

본 문서에서는 CreateMutex를 이용하여 세션에 상관없이 PC에서 단 1개의 프로그램만 실행시켜 다중 실행을 방지하는 방법에 대해서 설명합니다.


본론
앞서 설명이 길었으므로, 바로 해결책을 아래 코드로 보여드리겠습니다.
var
  strMsg: string;
  hMutex: THandle;
begin
  hMutex := CreateMutex(nil, True, 'Global\TEST_MUTEX');
  if (0 <> hMutex) and (ERROR_ALREADY_EXISTS = GetLastError) then
  begin
    strMsg := '이미 "TEST.exe"가 실행중입니다.'#13#10#13#10 +
        '기존 프로세스를 종료한 이후에 다시 실행하여 주십시요.';
    MessageBox(0, PChar(strMsg), PChar(TITLE_STRING), MB_OK or MB_ICONSTOP);
    Exit;
  end;

  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;

  CloseHandle(hMutex);


MSDN의 CreateMutex 설명을 보면, 마지막 Mutex 이름을 입력하는 부분에서 "Global\", "Local\" 접두어를 줄 수 있다고 되어 있습니다. 이중에서 "Global\" 접두어를 주면, 세션에 상관없이 PC내에서 유일한 이름으로 Mutex 이름을 지정하여 사용하게 되는 것입니다. 예를 들어, "TEST_MUTEX"라는 뮤텍스를 만들 때, 0번 세션에서 "Global\TEST_MUTEX"라고 CreateMutex를 한 다음에 1번 세션에서 다시 동일한 이름("Global\TEST_MUTEX")으로 CreateMutex를 하게 되면, ERROR_ALREADY_EXISTS 오류가 발생하게 됩니다.

아래는 MSDN에서 발췌한 내용입니다.

The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.

Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character.


결론
간단하게 CreateMutex를 이용하여 다중 실행을 방지하는 방법에 대해서 살펴 보았습니다. CreateMutex를 이용하지 않고 FindWindow 등 다른 여러 가지 방법이 많이 있습니다만, 윈도우즈 세션에 상관없이 서비스(Service)와 같이 PC 자체에서 단 1개의 프로그램을 실행해야하는 경우에 CreateMutex를 이용하면 매우 손쉽게 처리할 수 있습니다.


참고자료
  • MSDN CreateMutex function 설명