Solved

How to use RegNotifyChangeKeyValue with a thread in c++

Posted on 2011-03-08
10
1,042 Views
Last Modified: 2012-05-11
How to use RegNotifyChangeKeyValue with a thread in c++
0
Comment
Question by:Eric_974
  • 6
  • 3
10 Comments
 
LVL 4

Expert Comment

by:parnasso
Comment Utility
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
0
 
LVL 4

Expert Comment

by:parnasso
Comment Utility
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)
0
 

Author Comment

by:Eric_974
Comment Utility
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

0
 
LVL 4

Expert Comment

by:parnasso
Comment Utility
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

0
 

Author Comment

by:Eric_974
Comment Utility
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
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 4

Expert Comment

by:parnasso
Comment Utility
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!
0
 
LVL 4

Expert Comment

by:parnasso
Comment Utility
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

0
 

Author Comment

by:Eric_974
Comment Utility
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 ?
0
 
LVL 4

Accepted Solution

by:
parnasso earned 250 total points
Comment Utility
Sorry, with this approach, i don't know how to get which event occured just after the event is signaled. For sure you have to do some workaround or do some research to try with another approach. The following post might help you:

Register for USB arrival
0
 
LVL 11

Assisted Solution

by:DeepuAbrahamK
DeepuAbrahamK earned 250 total points
Comment Utility
To answer your last question:

Note: I haven't compiled it yet but this should help I guess.
DWORD  dwFilter = 0x00;
   HEVENT hEvent[4];


   for (int i = 0; i<4; i++)
   {
      hEvent[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
   }

   dwFilter = REG_NOTIFY_CHANGE_NAME;
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[0], 
                                        TRUE);


   dwFilter = REG_NOTIFY_CHANGE_ATTRIBUTES;
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[1], 
                                        TRUE);


   dwFilter = REG_NOTIFY_CHANGE_LAST_SET;
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[2], 
                                        TRUE);

   dwFilter = REG_NOTIFY_CHANGE_SECURITY; 
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[3], 
                                        TRUE);

    dwEvent = WaitForMultipleObjects( 
        4,           // number of objects in array
        hEvent,     // array of objects
        FALSE,       // wait for any object
        5000);       // five-second wait
	
   switch (dwEvent) 
   { 
        // hEvent[0] was signaled or REG_NOTIFY_CHANGE_NAME occurred
        case WAIT_OBJECT_0 + 0: 
            printf("REG_NOTIFY_CHANGE_NAME event was signaled.\n");
            break; 

        // hEvent[1] was signaled or REG_NOTIFY_CHANGE_ATTRIBUTES occurred
        case WAIT_OBJECT_0 + 1: 
            printf("REG_NOTIFY_CHANGE_ATTRIBUTES event was signaled.\n");
            break;

        // hEvent[2] was signaled or REG_NOTIFY_CHANGE_LAST_SET occurred
        case WAIT_OBJECT_0 + 2: 
            printf("REG_NOTIFY_CHANGE_LAST_SET event was signaled.\n");
            break;
   
       // hEvent[3] was signaled or REG_NOTIFY_CHANGE_SECURITY occurred
        case WAIT_OBJECT_0 + 3: 
            printf("REG_NOTIFY_CHANGE_SECURITY event was signaled.\n");
            break;
   }

Open in new window

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now