고수닷넷 - 데미소다오렌지님
1. Introduction
MS Windows에서 구동되는 몇몇 프로그램들은 중복 실행이 되지 않는다. Windows의 태스크 매니저나 MSN 메신저등이 대표적인 예라고 할 수 있다. 이러한 경우에 사용할 수 있는 방법은 여러가지가 있다. 이 문서에서는 뮤텍스를 사용한 방법을 살펴보도록 할 것이다.
명명된(named) 커널 오브젝트의 경우 프로세스의 경계를 넘어서 공유할 수 있다. 그래서 동일한 이름의 뮤텍스를 생성하려고 하면 이미 생성된 경우는 기존의 핸들을 넘겨주고, 참조 카운트만 증가시키게 된다. 이 때, GetLastError를 해보면 ERROR_ALREADY_EXISTS가 나오게 된다. 만약 존재하지 않는 뮤텍스였고, 생성된 것이라면 0이 나오게 된다.
2. Codes
class CSingleInstance
{
private:
HANDLE m_hGlbMutex; // 전역 뮤텍스 핸들
public:
CSingleInstance(LPCTSTR lpszMutexName="AppSingInstCheck");
~CSingleInstance();
BOOL IsExist();
};
클래스의 선언부다. 위 클래스의 생성자에 문자열을 넣게 되어 있으며, 그것은 해당 어플리케이션의 중복 실행을 테스트하는 뮤텍스의 이름으로 사용된다. IsExist()멤버를 사용해서 이미 실행된 인스턴스가 존재하는지 검사할 수 있다.
이 클래스의 인스턴스는 프로세스가 존재하는 동안 제거되어서는 안된다는 점이다. 따라서 전역 변수등으로 만들어야 한다. 만약 프로세스가 실행중인데, 이 클래스가 소멸된다면 우리의 목적인 중복 실행 방지가 되지 않는다.
//
// 전역 뮤텍스를 생성해서 중복 실행 체크
//
// 파라미터
// lpszMutexName [in] 뮤텍스 이름
CSingleInstance::CSingleInstance(LPCTSTR lpszMutexName)
{
TCHAR szBuffer[MAX_PATH] = {0};
// 2000 이상의 경우는 Global 오브젝트 이름을 지원한다.
if(LOWORD(GetVersion()) >= 5)
strcpy(szBuffer, "Global\\");
strcat(szBuffer, lpszMutexName);
m_hGlbMutex = CreateMutex(NULL, FALSE, szBuffer);
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(m_hGlbMutex);
m_hGlbMutex = NULL;
}
}
// 뮤텍스 핸들 해제
CSingleInstance::~CSingleInstance()
{
if(m_hGlbMutex)
CloseHandle(m_hGlbMutex);
}
//
// 이미 실행된 프로그램이 있는지 검사
//
// 파라미터 없음
//
// 리턴값
// 존재하는 경우 1을, 처음 실행인 경우 0을 리턴함
BOOL CSingleInstance::IsExist()
{
return m_hGlbMutex == NULL;
}
위는 실제 구현 내용이다. 생성자에서 뮤텍스를 생성하고, 소멸자에선 해당 뮤텍스를 제거한다. 별로 어려운 내용은 없다. 버전을 검사해서 2000이상의 경우 Global 객체를 지원하므로, 버전을 검사하여 이름앞에 Global을 자동적으로 붙여준다.
Leave your greetings.
감사합니당~ ^-^
2008/03/29 23:10 [ Permalink : Modify/Delete : Reply ]계산기 만드는데 참고 하겠습니다. ~ ^^
유용하게 쓰이길 바랍니다.
2008/04/03 08:12 [ Permalink : Modify/Delete ]