Solved

multiple notifications from FindFirstChangeNotification

Posted on 2003-10-25
6
2,086 Views
Last Modified: 2013-12-03
hello,

i am using FindFirstChangeNotification and listening for FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_LAST_WRITE
on multiple directories.

      DWORD word;
    // Wait for notification.
 
    dwWaitStatus = MsgWaitForMultipleObjects((DWORD)numberofhandles, ChangeHandles,
        FALSE, INFINITE,QS_POSTMESSAGE);

when a message comes in

 do {      //wait and see if we get multiple of the same message and skip them we  
                   only want to run once
      FindNextChangeNotification(ChangeHandles[dwWaitStatus]);
       word = WaitForSingleObject(ChangeHandles[dwWaitStatus], 1000);
        
   } while(word == dwWaitStatus);


The problem i am having is when i trigger a last write by adding to a file and saving it i think i am getting multiple different  notifications.
my little do while loop catches them if its the same message   . what other message am i recieving and how to i make it so i only hand the last write message.

thanks
0
Comment
Question by:tryonix
  • 2
  • 2
  • 2
6 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9620467
What application are you using to add something to a file? It might well be that a backup copy of the file is created. Have you tried using 'ReadDirectoryChangesW()' to find out what happens?
0
 
LVL 86

Expert Comment

by:jkr
ID: 9620477
0
 
LVL 16

Expert Comment

by:_nn_
ID: 9620505
Well, I'm not sure I understand, but I'd like to point a small mistake here

    dwWaitStatus = MsgWaitForMultipleObjects((DWORD)numberofhandles, ChangeHandles,
        FALSE, INFINITE,QS_POSTMESSAGE);

In case something "happens" in one of the directories, let's assume it's the fifth handle in the array, then the return value will be : WAIT_OBJECT_0 + 4. It could be (I honestly don't know) that WAIT_OBJECT_0 == 0, but you should not assume that.

Now whether or not WAIT_OBJECT_0 is 0, the following code isn't correct :

do {     //wait and see if we get multiple of the same message and skip them we  
                   only want to run once
      FindNextChangeNotification(ChangeHandles[dwWaitStatus]);
       word = WaitForSingleObject(ChangeHandles[dwWaitStatus], 1000);
       
   } while(word == dwWaitStatus);

because
- ChangeHandles[dwWaitStatus] is possibly out of bounds
- WaitForSingleObject() will return WAIT_OBJECT_0 in case an event happened, which will always be different than WAIT_OBJECT_0 + 4 and/or 4

So, I'd replace that line with

   } while(word == WAIT_OBJECT_0);

and make sure that dwWaitStatus has the proper value.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:tryonix
ID: 9621447
okay i am a little confused with this method
here is the code i have
can u tell me what i am doing wrong?

while (running)
{
      DWORD word;
    // Wait for notification.
 
    dwWaitStatus = MsgWaitForMultipleObjects((DWORD)numberofhandles, ChangeHandles,
        FALSE, INFINITE,QS_POSTMESSAGE);
      if (dwWaitStatus == i)
      {
            MSG msg ;

        // Read all of the messages in this next loop,
        // removing each message as we read it.
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // If it's a quit message, we're out of here.
            if (msg.message == WM_QUIT)  
                  {
                              running =false; //end loop
                  }
            else// Otherwise, dispatch the message.
            {
                        DispatchMessage(&msg);
                  }
        } // End of PeekMessage while loop.

      }
      else
      {

   do {      //wait and see if we get multiple of the same message and skip them we only want to run once
      FindNextChangeNotification(ChangeHandles[dwWaitStatus]);
       word = WaitForSingleObject(ChangeHandles[dwWaitStatus], 1000);
        
   } while(word == dwWaitStatus);

//now do what i want
0
 

Author Comment

by:tryonix
ID: 9621481
made a mistake in last post  with

if (dwWaitStatus == i)

should be this

      if (dwWaitStatus == numberofhandles)
sorry
0
 
LVL 16

Accepted Solution

by:
_nn_ earned 500 total points
ID: 9622141
 while (running)
  {
    DWORD word;
    // Wait for notification.
   
    dwWaitStatus = MsgWaitForMultipleObjects((DWORD)numberofhandles, ChangeHandles,
      FALSE, INFINITE,QS_POSTMESSAGE);
    if (dwWaitStatus == WAIT_OBJECT_0+numberofhandles)
    {
      MSG msg ;
     
      // Read all of the messages in this next loop,
      // removing each message as we read it.
      while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
        // If it's a quit message, we're out of here.
        if (msg.message == WM_QUIT)  
        {
          running =false; //end loop
        }
        else// Otherwise, dispatch the message.
        {
          DispatchMessage(&msg);
        }
      } // End of PeekMessage while loop.
     
    }
    else if (dwWaitStatus >= WAIT_OBJECT_0
             && dwWaitStatus < WAIT_OBJECT_0+numberofhandles)
    {
      dwWaitStatus -= WAIT_OBJECT_0;
      // now dwWaitStatus is a value between 0 and numberofhandles

      do {     //wait and see if we get multiple of the same message and skip them we only want to run once
        FindNextChangeNotification(ChangeHandles[dwWaitStatus]);
        word = WaitForSingleObject(ChangeHandles[dwWaitStatus], 1000);
       
      } while(word == WAIT_OBJECT_0);

      // I guess, the processing goes here

    }
    else
    {
      // MsgWaitForMultipleObjects may return other values
      // like WAIT_ABANDONED_0
    }

  }
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

910 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

25 Experts available now in Live!

Get 1:1 Help Now