在线请教:我用findfirstchangenotification监视文件夹是否不改变,但我如何知道是该文件夹下哪一个文件的改变谢谢

解决方案 »

  1.   

    // FileWatch.cpp: implementation of the CFileWatch class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "WatchFile.h"
    #include "FileWatch.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CFileWatch::CFileWatch()
    {
    hCompPort=NULL; 
    m_bStop = true;
    numDirs = 0;
    memset(DirInfo,0,sizeof(DIRECTORY_INFO)*MAX_DIRS);
    }CFileWatch::~CFileWatch()
    {}
    BOOL CFileWatch::WatchDirectories( char *lpStrpath )
    {
    if(numDirs > MAX_DIRS)
    return false;
    DirInfo[numDirs].hDir = CreateFile( lpStrpath,
    FILE_LIST_DIRECTORY,
    FILE_SHARE_READ |
    FILE_SHARE_WRITE |
    FILE_SHARE_DELETE,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS |
    FILE_FLAG_OVERLAPPED,
    NULL);

    if( DirInfo[numDirs].hDir == INVALID_HANDLE_VALUE )
    {
    return false;
    }
        strcpy( DirInfo[numDirs].lpszDirName, lpStrpath );
    hCompPort=CreateIoCompletionPort( DirInfo[numDirs].hDir,
    hCompPort,(DWORD) &DirInfo[numDirs],0);
    numDirs ++;
    if(m_bStop)
    {
        AfxBeginThread(Watch,this);
    m_bStop = !m_bStop;
    }
    return true;
    }
    void CFileWatch::WatchDirectories( HANDLE hCompPort )
    {
        DWORD   i;
    //    DWORD   tid;
    //    HANDLE  hThread;
        // Start watching each of the directories of interest    for (i=0;i<numDirs;i++)
        {
            if(!ReadDirectoryChangesW( DirInfo[i].hDir,
                                   DirInfo[i].lpBuffer,
                                   MAX_BUFFER,
                                   TRUE,
                                   FILE_NOTIFY_CHANGE_LAST_WRITE,
                                   &DirInfo[i].dwBufLength,
       &DirInfo[i].Overlapped,
                                   NULL))
    {
    int tt=GetLastError();
    }
        }    // Create a thread to sit on the directory changes CWinThread *pThread =  AfxBeginThread(HandleDirectoryChange,(LPVOID)hCompPort);
    //    hThread = CreateThread( NULL,
    //                            0,
    //                            (LPTHREAD_START_ROUTINE) HandleDirectoryChange,(LPVOID)
    //                            hCompPort,
    //                            0,
    //                            &tid);
        WaitForSingleObject( pThread->m_hThread, INFINITE );
        CloseHandle( pThread->m_hThread );
    }
    void CFileWatch::CheckChangedFile( LPDIRECTORY_INFO lpdi,
                                  PFILE_NOTIFY_INFORMATION lpfni)
    {
    TRACE("test is ok\n");
    /*
        TCHAR      szFullPathName[MAX_PATH];
        TCHAR      *p;
        HANDLE     hFile;
        FILETIME   LocalFileTime;
        SYSTEMTIME SystemTime;
        BY_HANDLE_FILE_INFORMATION FileInfo;    p = FileList;    while(*p && lstrcmpi(p,lpfni->FileName))
            p+=(lstrlen(p)+1);    if(*p)
        {
            lstrcpy( szFullPathName, lpdi->lpszDirName );
            lstrcat( szFullPathName, L"\\" );
            lstrcat( szFullPathName, lpfni->FileName );        // we assume that the file was changed, since 
            // that is the only thing we look for in this sample
            wprintf( L"%s changed,", szFullPathName );        hFile=CreateFile( szFullPathName,
                              GENERIC_READ,
                              FILE_SHARE_READ,
                              NULL,
                              OPEN_EXISTING,
                              FILE_FLAG_SEQUENTIAL_SCAN,
                              0);        GetFileInformationByHandle( hFile, &FileInfo );        FileTimeToLocalFileTime( &(FileInfo.ftLastWriteTime), &LocalFileTime );        FileTimeToSystemTime( &LocalFileTime, &SystemTime );        wprintf( L" Size = %d bytes,", FileInfo.nFileSizeLow );
            wprintf( L" Last Access = %02d/%02d/%02d %02d:%02d:%02d",
                     SystemTime.wMonth,
                     SystemTime.wDay,
                     SystemTime.wYear,
                     SystemTime.wHour,
                     SystemTime.wMinute,
                     SystemTime.wSecond );        CloseHandle( hFile );        wprintf( L"\n" );
        }
    */
    }
    UINT CFileWatch::HandleDirectoryChange( LPVOID pParam )
    {
    HANDLE dwCompletionPort =  (HANDLE) pParam;
    if(dwCompletionPort == NULL)
    return 0;
        DWORD numBytes;
        DWORD cbOffset;
        LPDIRECTORY_INFO di;
        LPOVERLAPPED lpOverlapped;
        PFILE_NOTIFY_INFORMATION fni;    do
        {
            // Retrieve the directory info for this directory
            // through the completion key
            GetQueuedCompletionStatus( (HANDLE) dwCompletionPort,
                                       &numBytes,
                                       (LPDWORD) &di,
                                       &lpOverlapped,
                                       INFINITE);
    int tt =0;        if ( di )
            {            fni = (PFILE_NOTIFY_INFORMATION)di->lpBuffer;            do
                {
                    cbOffset = fni->NextEntryOffset;                if( fni->Action == FILE_ACTION_MODIFIED )
    {
                        CheckChangedFile( di, fni );
    }                fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE) fni + cbOffset);            } while( cbOffset );            // Reissue the watch command
                ReadDirectoryChangesW( di->hDir,di->lpBuffer,
                                       MAX_BUFFER,
                                       TRUE,
                                       FILE_NOTIFY_CHANGE_LAST_WRITE,
                                       &di->dwBufLength,
                                       &di->Overlapped,
                                       NULL);
            }    } while( di ); return 0;
    }void CFileWatch::Reset()
    {}void CFileWatch::StopWatch()
    {
        PostQueuedCompletionStatus( hCompPort, 0, 0, NULL );
    Reset();
    }UINT CFileWatch::Watch(LPVOID pParam)
    {
    CFileWatch *watch =(CFileWatch*)pParam;
    if(watch == NULL)
    return 1;
    watch->WatchDirectories(watch->hCompPort);
    return 0;}
      

  2.   

    或者使用SHChangeNotifyRegister/SHChangeNotifyDeregister.LRESULT CThumbnailListCtrl::OnFileChanged(WPARAM wParam, LPARAM lParam)
    {
    SHNotifyInfo* pShellInfo = (SHNotifyInfo*)wParam;

    if(m_strCurrentDir.IsEmpty())
    {
    return 0;
    } switch(lParam)
    {
        case SHCNE_DELETE:
    {
    //deleted file
    CString strPathName = GetPathFromPIDL(pShellInfo->dwItem1);
    CString strPath = ExtractPath(strPathName); break;
    }............
    }