SW 개발

[win32API] 어플리케이션중복실행방지

. . . 2010. 3. 24. 01:18
반응형
  • 출처 : 인터넷어딘가.. 오래전 자료라 출처를 잘모르겠습니다.
  • 기타사항 : winCE / Windows Moblie 공통. 틀린사항은 댓글로 수정바랍니다.

중복실행방지

많은 개발자분들께서 테스트용으로 작성하는 간단한 어플이 MFC기반 Dialog Based Application이죠... (경우에 따라서...) 그 어플이 중복실행되지 않게 하기 위해서 FindWindow()함수를 사용합니다.

카 페내에 이와 관련한 자료가 몇몇 있기는 한데....정리가 안된듯 하여 정리겸 제 경험을 끄적거려봅니다.

우선, Dialog Based Application이 처음 시작되는 부분이...

CxxxxApp::InitInstance() 함수입니다.

BOOL CxxxxApp::InitInstance() 
{ 
    // To check if the previous process is running. 
    HWND hWnd = FindWindow(NULL, L"Title of Dialog Window"); 
    if( hWnd ) 
    { 
      SetForegroundWindow(hWnd); 
      return FALSE; 
    }

    CxxxxDlg dlg; 
    m_pMainWnd = &dlg; 
    int nResponse = dlg.DoModal(); 
    (...중략)

    return FALSE; 
}

우리가 생성한 Dialog Based Application의 Window는 CDialog Class에서 상속받은 CxxxxDlg Class입니다.

class CxxxxDlg : public CDialog

CxxxxDlg Class를 생성하기 전에 FindWindow()함수를 호출하여 이전에 이미 프로세스가 실행중인지 판단하는데, CE 에서는 첫번째 인자로 넘겨줘야하는 Class Name은 L"Dialog"입니다. Remote Spy++로 해당 프로세스의 정보를 보면 클래스명을 알 수 있습니다. Dialog라는 Class명을 가진 프로세스가 상당수 존재할 수 있으므로 Class명으로 프로세스를 찾지 않고 Window Title을 가지고 프로세스를 찾습니다. 만약, 이전에 실행중인 동일한 Window Title을 가진 프로세스가 존재한다면, 이전 프로세스를 전면에 활성화시켜 보여주고 자기자신의 프로세스는 종료하게 되도록 구현한 것입니다.

간단한 팁이지만, 정확한 이해없이 가끔 잘못 사용하고 계시는 분들이 있어서 정리해보았습니다. 혹시, 잘못된 부분이나 오해의 소지가 있는 부분이 있으면 바로 지적해주시면 내용 보완하겠습니다. ^^

  • FindWindow() 함수에 대해서는...

    • ms-help://MS.WindowsCE.500/wceshellui5/html/wce50lrfFindWindow.htm
  • SetForegroundWindow() 함수에 대해서는...

    • ms-help://MS.WindowsCE.500/wceshellui5/html/wce50lrfSetForegroundWindow.htm

실제예제

MFC 다이얼로그 기반이라면 InitInstance함수 안에 다음 코드를 넣으시면 됩니다.

FD_Ctrl 이라는 문자열은 프로그램명(윈도우 네임)입니다.

////////////////////////////////////////////////////////////////////////// 
// 1. 프로그램 다중 실행 방지 
////////////////////////////////////////////////////////////////////////// 
// Mutex 생성 

HANDLE hMutexOneInstance = ::CreateMutex(NULL, TRUE, _T("FD_Ctrl")); 
TRACE(_T("*** FD_Ctrl ***")); 

BOOL bFound = FALSE; 

// 만약 이미 만들어져 있다면 Instance가 이미 존재함 
if(::GetLastError() == ERROR_ALREADY_EXISTS) 
    bFound = TRUE; 
if(hMutexOneInstance) 
    ::ReleaseMutex(hMutexOneInstance); 

// 이미 하나의 Instance가 존재하면 프로그램 종료 
if(bFound) 
{ 
    HWND hWnd=::FindWindow(_T("Dialog"), _T("FD_Ctrl")); 
    if(hWnd!=NULL) 
    { 
    ::SetForegroundWindow(hWnd); 
    }

    return FALSE; 
}

반응형