title: WaitForSingleObject with FindFirstChangeNotification not behaving as expected
body: <p>I have to find out if there is a new file in a directory on Windows. Following this MSDN example (<a href="https://docs.microsoft.com/en-us/windows/win32/fileio/obtaining-directory-change-notifications" rel="nofollow noreferrer">Obtaining Directory Change Notifications</a>), I came up with the following test program:</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;Windows.h&gt;
  #include &lt;vector&gt;
  #include &lt;string&gt;
  
  std::string FindNewFile(std::vector&lt;std::string&gt;&amp; vsNewFileList, std::vector&lt;std::string&gt;&amp; vsOldFileList)
  {
      std::string sNewFileName;
      int nScore = 0;
      for (auto&amp; newFile : vsNewFileList)
      {
          nScore = 0;
          for (auto&amp; oldFile : vsOldFileList)
              if(!newFile.compare(oldFile))
                  nScore++;
          if (nScore!=1)
          {
              sNewFileName = newFile;
              break;
          }
      }
      return sNewFileName;
  }
  
  void GetCurrentFilesInDir(std::string sDir, std::vector&lt;std::string&gt;&amp; vsFileList)
  {
      WIN32_FIND_DATA ffd;
      sDir += &quot;\\*&quot;;
      std::wstring wStr = std::wstring(sDir.begin(), sDir.end());
      LPCWSTR lpcwsDir = (LPCWSTR)wStr.c_str();
      HANDLE hFind = FindFirstFile(lpcwsDir, &amp;ffd);
      if (hFind == INVALID_HANDLE_VALUE)
      {
          std::cout &lt;&lt; &quot;Nope\n&quot;;
          return;
      }
      vsFileList.clear();
      do
      {
          int nSize = WideCharToMultiByte(CP_ACP, 0, ffd.cFileName, -1, 0, 0, 0, 0);
          char* pcStr = new char[nSize];
          WideCharToMultiByte(CP_ACP, 0, ffd.cFileName, -1, pcStr, nSize, 0, 0);
          //std::cout &lt;&lt; pcStr &lt;&lt; &quot;\n&quot;;
          vsFileList.push_back(std::string(pcStr));
          delete[] pcStr;
      } while (FindNextFile(hFind, &amp;ffd) != 0);
   }
  
  int main()
  {
      // watch the foo directory for new files
      std::string sDir = &quot;C:\\foo&quot;;
  
      std::vector&lt;std::string&gt; vsOldFileList, vsNewFileList;
      GetCurrentFilesInDir(sDir, vsOldFileList);
      std::wstring wStr = std::wstring(sDir.begin(), sDir.end());
      LPCWSTR lpcwsDir = (LPCWSTR)wStr.c_str();
      DWORD dwWaitStatus;
      HANDLE dwChangeHandle;
      dwChangeHandle = FindFirstChangeNotification(
          lpcwsDir,
          FALSE,
          FILE_NOTIFY_CHANGE_FILE_NAME);
  
      while (TRUE)
      {
          // returns multiple times before and after new file appears!!
          dwWaitStatus = WaitForSingleObject(dwChangeHandle, INFINITE);
          switch(dwWaitStatus)
          {
          case WAIT_OBJECT_0:
              GetCurrentFilesInDir(sDir, vsNewFileList);
              std::string sNewFileName = FindNewFile(vsNewFileList, vsOldFileList);
              std::cout &lt;&lt; sNewFileName &lt;&lt; &quot;\n&quot;;
              GetCurrentFilesInDir(sDir, vsOldFileList);
              FindNextChangeNotification(dwChangeHandle);
              break;
          }
      }
  }
  </code></pre>
  <p>The problem is that, when I save a new file in <code>C:\foo</code> (for instance, using Notepad++ to &quot;Save As&quot; an open <code>.txt</code> file in <code>C:\foo</code>), the call to <code>WaitForSingleObject()</code> in the <code>while</code> loop will return 0 multiple times. Since my <code>FindNewFile()</code> method returns an empty string if there is no new file in the directory, I will get output like:</p>
  <pre class="lang-none prettyprint-override"><code>a.txt
  
  
  </code></pre>
  <p>or:</p>
  <pre class="lang-none prettyprint-override"><code>
  b.txt
  
  </code></pre>
  <p>Or even:</p>
  <pre><code>c.txt
  
  c.txt
  
  </code></pre>
  <p>Can someone explain what I am missing here?</p>