본문 바로가기

3.구현/VC++

Registry(레지스트리) 변경을 감시하여 이벤트 처리하기

이는 레지스트리 변경음 감시하여 Notify를 해주는 기능을 구현하다. 아래 구현은 Win32에 기반을 두었고, 콘솔 프로젝트 하에서 테스트를 하였다.

http://ospace.tistory.com/(ospace114@empal.com) 2008.08.07

주요 API

사용 주요 API는 다음과 같다.

레지스트리 관련

  • RegOpenKeyEx(): 특정 레지스트리 키를 열기위해서 사용(KEY_NOTIFY플래그 반드시 사용)
  • RegNotifyChangeKeyValue(): 앞에서 열려진 키값을 Notify하기 위해 사용
  • RegCloseKey()

기타

  • CreateEvent(): Notify에 사용할 이벤트 핸들러
  • CloseHandle(): 열려진 핸들러 닫기
  • WaitForSingleObject(): 특정 핸들러의 액션을 대기하기 위해 사용

처리로직

처리되는 로직은 다음과 같다.

1) 변경 감시 원하는 레지스트리 키를 열기. 이때 KEY_NOTIFY 플래그를 받드시 지정.
2) 이벤트 핸들을 생성
3) 열려진 키를 Notify하도록 설정
3) Notify가 올때까지 대기
4) 변경이 감지되면 원하는 처리함

예제를 보기 전에 간단하게 레지스트리를 보자.

키는 레지스트리 편집기에서 보면 왼쪽창에 폴더 모양으로 있는 것이다. 해당 키를 선택했을 경우 위 그림처럼 나오는 것이 키에 대한 값이다. 값 타입은 총 5가지로 되어 있다.

예제

실제 코드는 아래 와 같다.

#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
 HKEY key = NULL;

 LRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_NOTIFY, &key);

 if(result != ERROR_SUCCESS) {
  printf("[ERROR] RegOpenKeyEx.\n");
  return -1;
 }

 DWORD regFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY;
 // REG_NOTIFY_CHANGE_LAST_SET - 레지스트리에 접근하고 있는 경우
 // REG_NOTIFY_CHANGE_NAME - 레지스트리 키가 변경, 삭제, 추가가 되는 경우
 // REG_NOTIFY_CHANGE_ATTRIBUTES - 레지스트리 키의 속성이 변경되는 경우 (사용권한설정 등)
 // REG_NOTIFY_CHANGE_SECURITY -  레지스트리 사용 권한 설정이 변경되는 경우

 HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

 printf("Start Notify Change Key Value.\n");

 // 임시로 5번 루프가 반복되도록 했다.
 for(int i=0; i < 5; ++i) {
  result = RegNotifyChangeKeyValue(key, true, regFilter, hEvent, true);

  if (result != ERROR_SUCCESS) {
   printf("[ERROR] RegNotifyChangeKeyValue.\n");
   return -1;
  }

  // Wait for an event to occur.
  switch(WaitForSingleObject(hEvent, INFINITE)) {
  case WAIT_FAILED:
    printf("[ERROR] WaitForSingleObject.\n");
    break;
  case WAIT_OBJECT_0:
    printf("[INFO] Registry changed.\n");   
   break;
  default:
   printf("[INFO] Unknown event.\n");
   break;
  }
 }

 RegCloseKey(key);
 CloseHandle(hEvent);

 return 0;
}

이상으로 마치겠다. 위의 코드가 Win32로 되어 있으므로 MFC에서도 그대로 사용할 수 있을 것이다. MFC에 자체에도 이를 이용한 객체가 있으니 좀더 세련되게 수정할 수 있을 것이다.
그러나 굳이 win32로 사용한 것은 사용범위나 용도가 더 다양하기때문이다.

위의 RegNotifyChangeKeyValue 함수의 플래그 중에서 REG_NOTIFY_CHANGE_ATTRIBUTES와 REG_NOTIFY_CHANGE_SECURITY는 거의 비슷한 행동을 보인다. 그 이유는 REG_NOTIFY_CHANGE_ATTRIBUTES가 해당 키의 속성이 변경되는 경우를 말한다. 그 속성이 현재 사용 권한 외에는 없기 때문이다. 즉 그게그것이다. 그러나 정확한 의미는 틀리므로 그 점에 주의 해야겠다. REG_NOTIFY_CHANGE_ATTRIBUTES가 더 포괄적인 범위를 가진다는 말이다.

보잘 것 없는 코드이지만 여러분에서 많은 도움이 되었으면 한다.

반응형