반응형
하드디스크 또는 파티션을 두 개 이상 사용하시는 분들이라면 대부분 음악파일이나 그림파일과 같은 파일을 다른 파티션에 저장하시는 분들이 많을것 같은데요..
이런분들은 유용하게 사용할 수 있을것 같네요.

1. 먼저, 시작 > 실행 > regedit 를 입력해서 레지스트리 편집창으로 들어가세요~~
2. 다음 경로를 찾아 이동합니다.
     HKEY_CURRENT_USER \ Software \ Microsoft \
          Windows \ CurrentVersion \ Explorer \ User Shell Folders
레지스트리 편집기 화면

레지스트리 편집기 화면


3. 음악은 My Music, 내 그림은 My Pictures 를 더블클릭 후
    원하는 경로로 수정하시면 됩니다.

이 밖에도 많은 항목이 있는데요.
아직 하나하나 어떤것들인지 확인해 보지 않았지만, 경로나 이름을 보면 대충 연결이 되는것 같네요.

그리고, My Music의 항목이 없는분들도 있습니다. 빈 공백에서 마우스 오른쪽 버튼을 클릭 후
새로만들기 > 확장가능한 문자열 값 을 선택하여 추가하시면 됩니다.
새로만들기 선택화면

새로만들기 선택화면

반응형

네임드 커널 오브젝트를 사용한 중복 실행 방지법.

1. Introduction

윈도우상에서 구동되는 특정 애플리케이션들의 경우 중복 실행이 방지되어야 한다. 대표적으로 MSN 메신저등을 들 수 있다. 메신저의 경우 중복해서 실행될 필요가 없다. 이렇게 한번만 실행되어야 하는 프로그램의 경우 어떻게 구현할 수 있을까? 윈도우 핸들을 찾는 방법, 커널 오브젝트를 사용하는 방법, 공유 세그먼트를 사용하는 방법 등이 있다. 여기서 우리가 구현할 방법은 그 중에서도 커널 오브젝트를 사용한 방법이다.

2. Single Instance

커널 오브젝트를 사용해서 어떻게 중복 실행을 방지할 수 있을까? 원리는 네임드(Named) 커널 오브젝트의 경우 프로세스 사이에 공유 된다는 점 이다. 이 점을 이용하면 다음과 같은 시나리오를 생각할 수 있다. 프로그램 시작시에 네임드 커널 오브젝트를 생성한다. 그리고 프로그램이 종료할 때 해당 오브젝트를 닫는다. 이렇게 되면 한번이라도 해당 프로그램이 실행되어 있으면 그 오브젝트가 생성되어 있는 셈이 된다. 만약에 두 번째 프로그램이 실행된 경우에 또 커널 오브젝트를 생성하려고 하면 커널에서는 이미 열러진 오브젝트 핸들을 넘겨주면서 해당 오브젝트의 레퍼런스 카운트를 1증가 시킨다. 그리고 끝으로 GetLastError값으로 ERROR_ALREADY_EXISTS를 설정한다. 따라서 간단히 우리는 커널 오브젝트 생성후 GetLastError를 조사해서 ERROR_ALREADY_EXISTS면 이미 프로그램이 한번 이상 실행되었다고 간주할 수 있다.

아래는 이러한 부수적인 작업들을 한번에 처리해주는 클래스의 소스다. 해당 클래스를 전역 내지는, 프로그램의 존속 기간동안 살아있는 클래스의 멤버 변수로 만든후에 IsExist함수를 호출해서 조사하면 된다. 만약 해당 값이 TRUE를 리턴한다면 프로그램을 바로 종료시키면 된다.
 

  1. class CSingleInstance  
  2. {  
  3. private:  
  4.         HANDLE  m_hMutex;  
  5.           
  6. public:  
  7.         CSingleInstance(LPCTSTR lpszMutexName = "SingleMutex");  
  8.         ~CSingleInstance();  
  9.           
  10.         BOOL IsExist() {return m_hMutex==NULL;}  
  11. };  
  12.  
  13. CSingleInstance::CSingleInstance(LPCTSTR lpszMutexName)  
  14. {  
  15.         m_hMutex = CreateMutex(NULL, TRUE, lpszMutexName);  
  16.         if(GetLastError() == ERROR_ALREADY_EXISTS)  
  17.         {  
  18.                 CloseHandle(m_hMutex);  
  19.                 m_hMutex = NULL;  
  20.         }  
  21. }  
  22.  
  23. CSingleInstance::~CSingleInstance()  
  24. {  
  25.         if(m_hMutex)  
  26.         {  
  27.                 CloseHandle(m_hMutex);  
  28.                 m_hMutex = NULL;  
  29.         }  
  30. }     
  31.      

3. How to use it?

그럼 실제로 MFC 프로그램에서 한번 사용해 보자. 일단 위 클래스 소스를 적당한 위치에 복사한다. 그리고 app 클래스의 멤버 변수로 아래와 같이 선언한다.

  1. CSingleInstance m_inst;  

그 다음은 app 클래스의 InitInstance 제일 앞에 아래와 같이 추가해보자.

  1. if(m_inst.IsExist())  
  2. {  
  3.         AfxMessageBox("다른 곳에 실행된 놈이 있습니다.");  
  4.         return FALSE;  
  5. }     
  6.      

그리고 프로그램을 실행해보면 두번이상은 실행이 되지 않는 것을 확인할 수 있다. 주의해야 할 점은 위 클래스의 뮤텍스 이름은 클래스의 생성자로 전달된다는 것이다. 따라서 뮤텍스 이름을 지정하고 싶은 경우에는 C++의 초기화 리스트를 사용해서 초기화 해야 한다.
------------------------------------------------------------------------------------------

※ 윈도우 핸들을 찾는 방법

FindWindow(LPCTSTR lpszClassName,  LPCTSTR lpszWindowName) 함수를 이용해 찾으면 된다.(이 때, 인수 값을 NULL로 넣으면 그 인수는 검색에서 제외한다.)

app 클래스의 InitInstance 메서드에 다음과 같이 추가하면 된다.

if (pWndPrev=FindWindow(NULL,"프로그램타이틀")) {
  if (pWndPrev->IsIconic())  pWndPrev->ShowWindow(SW_RESTORE);

   pWndChild = pWndPrev->GetLastActivePopup();
  pWndChild->SetForegroundWindow();

  return FALSE;
}


※ 네임드(Named) 커널 오브젝트를 이용하는 방법

프로세스간 공유가 가능한 뮤텍스나, 세마포어와 같은 네임드 커널 오브젝트를 사용하면 된다.
프로그램 실행시에 오브젝트를 생성하고 프로그램 종료시에 오브젝트를 제거하면, 프로그램 실행 중에는 오브젝트가 생성되어 있으므로 만약에 두 번째 프로그램이 실행된 경우에 또 오브젝트를 생성하려고 하면 커널에서는 이미 열러진 오브젝트 핸들을 넘겨주면서 해당 오브젝트의 레퍼런스 카운트를 하나 증가 시킨다. 그리고 끝으로 GetLastError값으로 ERROR_ALREADY_EXISTS를 설정한다.

app 클래스의 InitInstance 메서드에 다음과 같이 추가하면 된다.

g_hMutex = CreateMutex(NULL, TRUE, "프로그램이름아무거나");  

if(GetLastError() == ERROR_ALREADY_EXISTS)  {  
   CloseHandle(g_hMutex);
   g_hMutex = NULL;

  return FALSE;
}

그리고 프로그램 종료시(OnDestroy 등)에는 뮤텍스를 해제하는 내용을 추가한다.

if (g_hMutex!=NULL)  ReleaseMutex(g_hMutex);
반응형
:: 2007년 06월 27일 ::

  Weekly Highlight
"Rational" 관련 최신 자료를 검색하고, RTube를 통해 Rational에 더욱 가까이 갈 수 있습니다.
   Local Contents
쾌속 학습팀 - 김창준 (dW Column)
멀티 패러다임 언어 D와 함께 하는 프로그래밍 - 이비오 (Open dW)
신기술 밀림 속 생존전략 Part 3: 프로젝트 현장의 이야기 - 안영회 (Special Issue)
진지한 취미가로서 즐겁게 살기 - 텔인포스 기술연구소 책임연구원, 고현철 님 (dW Interview)
   최신 기술자료 (한글)
Eclipse용 Ajax Toolkit Framework [오픈 소스]
이클립스, ATP, Dojo를 사용하여, 프레임웍을 설치하고 Ajax 애플리케이션을 구현하는 방법을 배워봅시다.
사람을 위한 자동화: 지속적인 피드백 [자바]
피드백은 Continuous Integration (CI)에 있어서 필수적인 것이며 사실상 CI 시스템의 혈액이라고 할 수 있습니다. 사람을 위한 자동화 시리즈에서는 CI 시스템에 적용할 수 있는 다양한 피드백 장치에 대해 설명합니다.
PHP 애플리케이션을 가장 빠르게, Part 3: Memcache 데몬을 사용하여 메모리에 데이터 저장(cache)하기 [오픈 소스]
Memcache 데몬(memcached)은 고성능 분산 객체 캐시로 애플리케이션과 데이터 스토어 중간에 설치되는 RAM의 객체를 보존합니다. 각각의 캐시 히트는 데이터베이스 서버의 라운드트립(roundtrip)을 대체하면서 애플리케이션의 속도를 높여줍니다.
Cell BE 프로세서의 고성능 애플리케이션 프로그래밍, Part 3: SPU [파워 아키텍처]
PPE와 통신하는 방법, CESOF 실행 파일을 만드는 방법, 16 바이트 버스 에러 의미 구분 방법 등을 설명합니다.
Graphical Editing Framework을 사용하여 이클립스 기반 애플리케이션 구현하기 [오픈 소스]
GEF를 사용하여 애플리케이션을 구현하는 초기 단계에 대해 배워봅시다. 이클립스의 그래픽 에디터를 만드는 프로세스를 시작하는 옵션에 대해서도 알아봅니다.
Real world Rails: Rails의 캐싱(Caching) [웹 개발]
일반적으로 Ruby on Rails는 캐싱에는 알맞지 않다고들 합니다. 하지만 상황이 나아졌습니다. Rails 실행 환경의 정적 캐싱, 동적 캐싱, 액션 캐싱, 부분 캐싱에 대해 알아봅시다.
   최신 튜토리얼 (한글)
이클립스용 GUI 빌더, Jigloo 시작하기 [오픈 소스]
Jigloo를 사용하여 워크플로우 애플리케이션용 UI를 구현하는 것이 얼마나 쉬운 일인지를 확인해 봅시다. 시각적 상속 같은 Jigloo의 고급 기능을 연구하고, 애플리케이션을 테스트 하며 이를 패키징 해봅니다.
WebSphere Application Server Community Edition용 Spring 애플리케이션 개발, Part 2 [WebSphere]
"이번 튜토리얼에서는 스프링(Spring)의 연결 관리 구조에 대해 살펴볼 것입니다. 이제 ContactDAOJDBC.java 클래스를 개발하는 방법과 연결 관리를 위해 연결 풀에 사용되는 널리 알려진 오픈소스만큼이나 간편한 스프링 고유의 구현 방법, WebSphere Application Server Community Edition의 연결 풀 구현을 사용하는 것이 얼마나 편리한지 배워보겠습니다.
   최신 SW 다운로드
Rational Software Architect V7.0
   로보코드 코리아컵 2007
로보코드 코리아컵 2007  

한국 IBM은 올해로 제4회를 맞는 자바 프로그램 경진대회인 로보코드 코리아컵 2007을 개최합니다. 입문자부터 전문 개발자까지 누구든지 쉽게 로봇을 만들어 참여할 수 있는 챔피언쉽에 자신만의 로봇을 만들어 친구와 동료와 실력을 겨루어 보세요! 참가하시는 모든 분께 참가상을 드립니다.

+ Recent posts