CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Dec 1998
    Posts
    97

    Unable to track all changes in a directory using FindNextChangeNotification

    HTML Code:
    Platform : Windows2000, XP,
    Microsoft Visual C++ .NET (Version 7.1),
    
    Hello,
    
    I need to process the files in a directory immediately the moment it gets
    deposited in a directory.
    I am trying to achieve this by using WaitForMultipleObjects ,
    FindFirstChangeNotification, FindNextChangeNotification in a While loop
    in the Run() of one of my worker threads of my multithread application.
    I get the events for the files that were deposited after the
    WaitForMultipleObjects was invoked in the while loop.
    However those files that get deposited in the folder in the split of second
    before the WaitForMultipleObjects is invoked are not getting reported i.e. I
    am not getting their handles.
    Is there any other API or code that can help me achieve the same without
    losing the notification of the files deposited in between?
    Any evident problem that you see as to why this should happen?
    
    Any pointers would be of great help
    Thanks and Regards
    Ganga
    (Please see excerpts of code below
    Code:
    int CABIEventWorkThread::Run()
    
    {
    
    ASSERT_VALID(GetWork());
    
    CDirEventReceiverWork* dirWrk =
    dynamic_cast<CDirEventReceiverWork*>(GetWork());
    
    
    try
    
    {
    
    COMMINFOCON con;
    
    dirWrk->GetEventDirectoryList(con);
    
    dirWrk->RunOnce();
    
    HANDLE* dwChangeHandles;
    
    
    DWORD timeout = GetCycleTime();
    
    BOOL waitAll = FALSE;
    
    DWORD dwWaitStatus;
    
    while (TRUE)
    
    {
    
    try
    
    {
    
    dirWrk->GetEventDirectoryList(con);
    
    m_pDirEventServer.WatchDirectories(con);
    
    dwChangeHandles = GetHandleList();
    
    
    int nHandles = m_pDirEventServer.GetHandleMap().size()+ 2;
    
    dwWaitStatus = WaitForMultipleObjects(nHandles, dwChangeHandles,
    
    waitAll, timeout);
    
    if(dwWaitStatus == WAIT_TIMEOUT )
    
    {
    
    //Refresh receiver list
    
    continue;
    
    }
    
    if((dwWaitStatus == WAIT_OBJECT_0 + 0) || (dwWaitStatus == WAIT_OBJECT_0 +
    1) )
    
    {
    
    //signalled kill event
    
    break;
    
    }
    
    if((dwWaitStatus <= (WAIT_OBJECT_0 +1)) || (dwWaitStatus >= nHandles))
    
    {
    
    ASSERT(false);
    
    ostringstream ost;
    
    ost << "Invalid wait return value [" << dwWaitStatus << "]";
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    continue;
    
    }
    
    
    if(dwWaitStatus == m_pDirEventServer.GetHandleMap().size())
    
    {
    
    //signalled kill event
    
    break;
    
    }
    
    
    try
    
    {
    
    CCommInfo ci = m_pDirEventServer.SetNextChangeNotification
    
    (dwWaitStatus , dwChangeHandles);
    
    dirWrk->SetCommInfo(ci);
    
    //Process the directory
    
    dirWrk->DoWork(GetWork());
    
    }
    
    catch(CABIException e)
    
    {
    
    ostringstream ost;
    
    ost << e.ReportError();
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    continue;
    
    }
    
    }
    
    catch(CABIException e)
    
    {
    
    ostringstream ost;
    
    ost << e.ReportError();
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    continue;
    
    }
    
    }
    
    }
    
    catch(...)
    
    {
    
    ostringstream ost;
    
    ost << "Caught Unknown Exception while doing Directory receiver Work";
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    }
    
    try
    
    {
    
    //signalled externally for killing myself
    
    EndWork(); //do derived shutdown
    
    }
    
    catch(CABIException& e)
    
    {
    
    ASSERT(false);
    
    }
    
    catch(CException* e)
    
    {
    
    ASSERT(false);
    
    char szErr[1024];
    
    e->GetErrorMessage(szErr, 1024);
    
    e->Delete();
    
    ostringstream ost;
    
    ost << "Caught CException while executing EndWork(), with error [" << szErr
    << "]. Rebulidng ABI Exception";
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    }
    
    catch(exception& e)
    
    {
    
    ASSERT(false);
    
    ostringstream ost;
    
    ost << "Caught exception while executing EndWork(), with error [" <<
    e.what() << "]. Rebulidng ABI Exception";
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    }
    
    catch(...)
    
    {
    
    //this should never happen unless there is problem destroying
    
    //work object (bad pointer)
    
    ASSERT(false);
    
    ostringstream ost;
    
    ost << "Caught unknown exception while executing EndWork(). Rebulidng ABI
    Exception";
    
    CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    }
    
    SetEvent(GetEventDead()); //signal to calling thread that i am done
    
    SetEvent(GetEventAnotherDead()); //signal to calling thread that i am done
    
    AfxEndThread(0,m_bAutoDelete);
    
    return 0;
    
    }
    
    void CDirEventServer::WatchDirectories(const COMMINFOCON& con)
    
    {
    
    HANDLE dwChangeHandle;
    
    TCHAR lpDrive[4];
    
    TCHAR lpFile[_MAX_FNAME];
    
    TCHAR lpExt[_MAX_EXT];
    
    StopWatch();
    
    for(COMMINFOCON::const_iterator It = con.begin(); It != con.end(); It++)
    
    {
    
    const CCommInfo& ci =(*It);
    
    
    string strPath = ci.GetRemoteDir();
    
    const TCHAR* lpDir = strPath.c_str();
    
    bool subDirState = ci.IsSubDirectory();
    
    _tsplitpath(lpDir, lpDrive, NULL, lpFile, lpExt);
    
    lpDrive[2] = (TCHAR)'\\';
    
    lpDrive[3] = (TCHAR)'\0';
    
    
    // Watch the directory for file creation and deletion.
    
    
    dwChangeHandle= FindFirstChangeNotification(
    
    lpDir, // directory to watch
    
    subDirState, // do not watch subtree
    
    FILE_NOTIFY_CHANGE_CREATION |
    
    FILE_NOTIFY_CHANGE_LAST_WRITE); // watch file name changes
    
    
    if (dwChangeHandle == INVALID_HANDLE_VALUE)
    
    {
    
    ostringstream ost;
    
    ost << "FindFirstChangeNotification returned an INVALID_HANDLE_VALUE";
    
    throw CABIException(PROGRAM_ERROR,ost.str(),__FILE__,__LINE__);
    
    }
    
    
    AddToHandleMap(dwChangeHandle, &ci);
    
    }
    
    }
    
    CCommInfo CDirEventServer::SetNextChangeNotification(long lWait, HANDLE*
    dwChangeHandles)
    
    {
    
    
    HANDLECOMMINFOMAP::iterator It =
    GetHandleMap().find(dwChangeHandles[lWait]);
    
    if (lWait >= 0 && It != GetHandleMap().end())
    
    {
    
    const CCommInfo* ci = (*It).second;
    
    
    ASSERT(lWait < GetHandleMap().size()+2);
    
    if (FindNextChangeNotification(
    
    dwChangeHandles[lWait]) == FALSE)
    
    {
    
    ostringstream ost;
    
    ost << "FindNextChangeNotification returned an INVALID_HANDLE_VALUE";
    
    throw CABIException(PROGRAM_ERROR,ost.str(),__FILE__,__LINE__);
    
    }
    
    return *ci;
    
    }
    
    else
    
    {
    
    ostringstream ost;
    
    ost << "Invalid Handle Wait state";
    
    throw CABIException(PROGRAM_ERROR, ost.str(), __FILE__, __LINE__);
    
    }
    
    }

  2. #2
    Join Date
    May 2005
    Location
    Oregon
    Posts
    3,725

    Re: Unable to track all changes in a directory using FindNextChangeNotification

    Here is a Sample code from MSDN .have a look on this.
    Code:
    DWORD dwWaitStatus; 
    HANDLE dwChangeHandles[2]; 
     
    // Watch the C:\WINDOWS directory for file creation and 
    // deletion. 
     
    dwChangeHandles[0] = FindFirstChangeNotification( 
        "C:\\WINDOWS",                 // directory to watch 
        FALSE,                         // do not watch the subtree 
        FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes 
     
    if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) 
        ExitProcess(GetLastError()); 
     
    // Watch the C:\ subtree for directory creation and 
    // deletion. 
     
    dwChangeHandles[1] = FindFirstChangeNotification( 
        "C:\\",                        // directory to watch 
        TRUE,                          // watch the subtree 
        FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir. name changes 
     
    if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) 
        ExitProcess(GetLastError()); 
     
    // Change notification is set. Now wait on both notification 
    // handles and refresh accordingly. 
     
    while (TRUE) 
    { 
     
        // Wait for notification.
     
        dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 
            FALSE, INFINITE); 
     
        switch (dwWaitStatus) 
        { 
            case WAIT_OBJECT_0: 
     
            // A file was created or deleted in C:\WINDOWS. 
            // Refresh this directory and restart the 
            // change notification. RefreshDirectory is an 
            // application-defined function. 
     
                RefreshDirectory("C:\\WINDOWS") 
                if ( FindNextChangeNotification( 
                        dwChangeHandles[0]) == FALSE ) 
                    ExitProcess(GetLastError()); 
                break; 
     
            case WAIT_OBJECT_0 + 1: 
     
            // A directory was created or deleted in C:\. 
            // Refresh the directory tree and restart the 
            // change notification. RefreshTree is an 
            // application-defined function. 
     
                RefreshTree("C:\\"); 
                if (FindNextChangeNotification( 
                        dwChangeHandles[1]) == FALSE) 
                    ExitProcess(GetLastError()); 
                break; 
     
            default: 
                ExitProcess(GetLastError()); 
        }
    }
    Thanx

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured