Link to home
Start Free TrialLog in
Avatar of Eric_974
Eric_974

asked on

How to use RegNotifyChangeKeyValue with a thread in c++

How to use RegNotifyChangeKeyValue with a thread in c++
Avatar of parnasso
parnasso
Flag of Italy image

The idea is to have a worker thread waiting for an event to be singaled.
If this fits your needs, you should:

1

Create an event with CreateEvent

2

Create a thread, pass the event handler to it, and call WaitForSingleObject

3

Call RegNotifyChangeKeyValue passing the event as the fourth parameter and TRUE in the fifth parameter (fAsynchronous ) TRUE)

hope this helps
I forgot to mention that within the created thread, in order to receive more than one event from the registry, you have to call RegNotifyChangeKeyValue after you receive the registry event (after WaitForSingleObject)
Avatar of Eric_974
Eric_974

ASKER

Thank's to reply. But im not sure to inderstand the second answer. Effectly I receive only one event. But why ? Here is my code :

HANDLE	handle_event = NULL, handle_thread = NULL;

DWORD	dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; 
HKEY	h_key_register;

DWORD WINAPI
Func_Thread (LPVOID lpParam) 
{
	lpParam;
	DWORD	dwWaitResult;

	dwWaitResult = WaitForSingleObject (handle_event, INFINITE);
	switch (dwWaitResult) {
		case WAIT_OBJECT_0:
...
			break; 
		
		default: 
			return 0; 
	}
    return 1;
}

void
Run_Thread ()
{
	DWORD	num_thread;

	handle_event = CreateEvent (NULL, TRUE, FALSE, "Register Event");
	handle_thread = CreateThread (NULL, 0, Func_Thread, NULL, 0, &num_thread); 
	if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_NOTIFY, &h_key_register) == ERROR_SUCCESS)
		RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
}

Open in new window

In the function func_thread please call RegNotifyChangeValue again keeping the same registry open handle,  like this:

HANDLE	handle_event = NULL, handle_thread = NULL;

DWORD	dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; 
HKEY	h_key_register;

DWORD WINAPI
Func_Thread (LPVOID lpParam) 
{
	lpParam;
	DWORD	dwWaitResult;

	dwWaitResult = WaitForSingleObject (handle_event, INFINITE);
	switch (dwWaitResult) {
		case WAIT_OBJECT_0:
                   // do something ...
                   // reissue the notify command
                   RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
			break; 
		
		default: 
			return 0; 
	}
    return 1;
}

void
Run_Thread ()
{
	DWORD	num_thread;

        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_NOTIFY, &h_key_register) == ERROR_SUCCESS)
        {
	     handle_event = CreateEvent (NULL, TRUE, FALSE, "Register Event");
	     handle_thread = CreateThread (NULL, 0, Func_Thread, NULL, 0, &num_thread); 
	
	     RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
         }
}

Open in new window

Thank's again for your answer. But i am sorry nothing happen after the first even !! I explain what i want to do :
I have a serial com on USB port. I need to know in my application when the serial/USB port has been unplugged and/or plugged at any time.

Thanks a lot for help
Don't surrender. Let's try another thing I've in my mind.
Create the event with autoreset in the line 33, that is:

 handle_event = CreateEvent (NULL, FALSE, FALSE, "Register Event");

I hope that was the problem!
Forget what I-ve posted before, I've found the issue: after the thread gets signaled it returns and never come back to another WaitForSingleObject. So I added an infite loop:

HANDLE	handle_event = NULL, handle_thread = NULL;

DWORD	dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; 
HKEY	h_key_register;

DWORD WINAPI
Func_Thread (LPVOID lpParam) 
{
	lpParam;
	DWORD	dwWaitResult;
        
         while(1)
         {

	   dwWaitResult = WaitForSingleObject (handle_event, INFINITE);
	   switch (dwWaitResult) {
		case WAIT_OBJECT_0:
                   // do something ...
                   // reissue the notify command
                   RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
			break; 
		
		default: 
			return 0; 
              }
	}
    return 1;
}

void
Run_Thread ()
{
	DWORD	num_thread;

        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_NOTIFY, &h_key_register) == ERROR_SUCCESS)
        {
	     handle_event = CreateEvent (NULL, TRUE, FALSE, "Register Event");
	     handle_thread = CreateThread (NULL, 0, Func_Thread, NULL, 0, &num_thread); 
	
	     RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
         }
}

Open in new window

Thanks a lot. It's works ! A last question. How can i know with event has occur ?  REG_NOTIFY_CHANGE_NAME, REG_NOTIFY_CHANGE_ATTRIBUTES, REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY ?
ASKER CERTIFIED SOLUTION
Avatar of parnasso
parnasso
Flag of Italy image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of Deepu Abraham
Deepu Abraham
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial