?
Solved

multiple notifications from FindFirstChangeNotification

Posted on 2003-10-25
6
Medium Priority
?
2,112 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 

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 2000 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

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
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…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

801 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