2014. 11. 7. 14:46

Registry 변경 감시를 위한 간단 코드 공유

레지스트리값이 변경되었는지를 감시하는 코드를 공유합니다. 보통 RegNotifyChangeKeyValue(...)가 사용되는데, Thread 사용 없이, IOCP와 thread pool등을 이용하여 간단히 구현한 코드로 구성되었습니다.


RegNotifyChangeKeyValue(...)는 변경이 감지되면, callback으로 호출해주는 것이 아니라, Event가 Set되도록 해줍니다. 그리고, 단발성 호출로, 다시 감시를 하려면, 해당 함수를 호출해줘야 합니다. Event Set이라는 특징으로 인해, Thread를 하나 만들어, 감시를 해야할 경우가 생길수도 있는데, 본 class, 즉, CNotifyRegistry에서는 RegisterWaitForSingleObject를 이용하여 Thread 생성없이 OS에서 제공하는 thread pool을 이용하도록 하였습니다. 그래서인지 코드가 매우 간단합니다.


일단 사용하려면, CNotifyRegistry를 상속받습니다.

그리고 아래와 같이 OnChanged를 재정의 합니다.

중요한 것은, OnChanged()는 Thread pool에서 호출되므로, 다른 Thead에서 호출될 수 있다는 점입니다.

이후의 StopNotifyRegistry() 함수는 OnChanged()가 종료될 때 까지 기라리게 되는데, 만일, OnChanged()가 StopNotifyRegistry() 호출 Thread가 종료될 때 까지 기다리는 논리가 들어간다면, Deadlock이 발생할 수 있으니, 조심하시기 바랍니다.


어떻든, 상속받은 class의 .h 입니다.

class CMyNotify : public CNotifyRegistry

{

public:

CMyNotify(void);

~CMyNotify(void);


protected:

// 변경되었을때 호출됨.

// 상속해서 재-정의 가능함

virtual VOID OnChanged(VOID);

};


아래는 상속받은 class의 .cpp입니다.

CMyNotify::CMyNotify(void)

{

}


CMyNotify::~CMyNotify(void)

{

}


VOID CMyNotify::OnChanged(VOID)

{

printf("Modified !!!!!!!!!!!!!\r\n");

}


이렇게하면 모두 준비된 것입니다. 만일, 재정의한 class에 Context를 전달하고 싶다면, 그냥 멤버 함수와 변수를 구현하면됩니다.


그럼 호출하는 방식은 아래와 같습니다.


CMyNotify cMyNoti;


if (FALSE == cMyNoti.StartNotifyRegistry(HKEY_LOCAL_MACHINE, 

 L"SOFTWARE\\_TEST_", 

 FALSE))

{

printf("Fail to Notify.\r\n");

assert(FALSE);

goto FINAL;

}

만일 상속받은 class 이름이 CMyNotify인 경우, 해당 instance를 만듭니다.

그리고 단순히 StartNotifyRegistry(...) 만 호출하면 됩니다.

처음 두개 Parameter는 감시할 Registry 정보로, 굳이 설명할 필요는 없을 듯 합니다.

세번째 Parameter는 SubKey까지 모두 감시할지 여부를 전달하면 됩니다.


위 함수는 Non-block 함수로 바로 리턴되는 함수임을 확인하시기 바랍니다.


마지막으로 아래와 같이, 감시를 종료할 수 있습니다.


cMyNoti.StopNotifyRegistry();


첨부된 NotiReg.exe를 실행하면, 아래와 같이 콘솔창이 뜹니다.

(실행전 HKLM\Software\_TEST_ Registry key가 있어야 합니다.)

Try to modify the registry [HKLM\SOFTWARE\_TEST_].

Press a key to Exit.

_


해당 Regisry에 값을 추가하거나 수정하면 아래와 같이 print됩니다.

Try to modify the registry [HKLM\SOFTWARE\_TEST_].

Press a key to Exit.

Modified !!!!!!!!!!!!!

Modified !!!!!!!!!!!!!

_


종료를 원한다면, 아무키를 누릅니다.

Try to modify the registry [HKLM\SOFTWARE\_TEST_].

Press a key to Exit.

Modified !!!!!!!!!!!!!

Modified !!!!!!!!!!!!!

계속하려면 아무 키나 누르십시오 . . . _


NotiReg.zip