ReadDirectoryChangesW在移动文件时不通知

时间:2015-08-06 09:33:40

标签: winapi filesystems filesystemwatcher readdirectorychangesw

我是这个Windows API的新手。我是项目中的GUI开发人员,我需要监视特定文件夹。我已经使用ReadDirectoryChangeW跟踪了Windows API中的每个步骤,但是当文件移动到其他目录(剪切/粘贴或删除以移动到垃圾箱)时,ReadDirectoryChangeW没有通知我。至少它应该通知为FILE_ACTION_RENAMED 它是Windows 7和ReadDirectorChangeW正在进行正常复制,paset,shift + delete,重命名

此代码是用Qt c ++编写的,其中QString是char * 这是我的代码

#include <windows.h>
#include <Winbase.h>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <qDebug>
#include <QThread>

#define MAX_DIRS 200
#define MAX_FILES 255
#define MAX_BUFFER 4096
#if 0
 extern "C" {
             WINBASEAPI BOOL WINAPI
             ReadDirectoryChangesW( HANDLE hDirectory,
             LPVOID lpBuffer, DWORD nBufferLength,
             BOOL bWatchSubtree, DWORD dwNotifyFilter,
             LPDWORD lpBytesReturned,
             LPOVERLAPPED lpOverlapped,
             LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
             );
 }

#endif

 class WatcherThread : public QThread
 {
     Q_OBJECT

 public:
     WatcherThread(LPCWSTR dir)
     {
         path = dir;
     }
     void run() Q_DECL_OVERRIDE {
         QString newDirName;
         char buf[2048];
         DWORD nRet;
         BOOL result=TRUE;
         char filename[MAX_PATH];

         //path = L"K:/Demo/bb";

         wchar_t* arr = (wchar_t*)path;
         printf("\nThe file  directory: [%s] \n", path);
         qDebug() << "WatchDirectory Watcher Path " << QString::fromWCharArray(arr);
         DirInfo[0].hDir = CreateFile (path, GENERIC_READ|FILE_LIST_DIRECTORY,
                                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                                       NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
                                       NULL);

         if(DirInfo[0].hDir == INVALID_HANDLE_VALUE)
         {
             qDebug() << "Can not open";
             return;
         }

         lstrcpy( DirInfo[0].lpszDirName, path);
         OVERLAPPED PollingOverlap;

         FILE_NOTIFY_INFORMATION pNotify[1024];
         int offset;
         PollingOverlap.OffsetHigh = 0;
         PollingOverlap.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);



         while(result)
         {
             result = ReadDirectoryChangesW(
                        DirInfo[0].hDir,// handle to the directory to be watched
                        (LPVOID)&pNotify,// pointer to the buffer to receive the read results
                        sizeof(pNotify),// length of lpBuffer
                        1,// flag for monitoring directory or directory tree
                        FILE_NOTIFY_CHANGE_DIR_NAME |  FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE  ,
                      &nRet,// number of bytes returned
                      &PollingOverlap,// pointer to structure needed for overlapped I/O
                      NULL);

             WaitForSingleObject(PollingOverlap.hEvent,INFINITE);
//             if(result)
//             {
             offset = 0;
             int rename = 0;
             char oldName[260];
             char newName[260];

             do
             {
                 //pNotify = (FILE_NOTIFY_INFORMATION*)((char*)buf + offset);
                 strcpy(filename, "");
                 int filenamelen = WideCharToMultiByte(CP_ACP, 0, pNotify[offset].FileName, pNotify[offset].FileNameLength/2, filename, sizeof(filename), NULL, NULL);
                 //filename[pNotify->FileNameLength/2] = ' ';

                 switch(pNotify[offset].Action)
                 {
                     case FILE_ACTION_ADDED:
                      qDebug() << "The FILE_ACTION_ADDED***********" << QString(filename).left(filenamelen);
                      emit onFileCopy(QString(filename).left(filenamelen));
                          break;
                     case FILE_ACTION_MODIFIED:
                        qDebug() << "The FILE_ACTION_MODIFIED" << QString(filename).left(filenamelen);

                         break;
                     case FILE_ACTION_REMOVED:
                         qDebug() << "The FILE_ACTION_REMOVED" << QString(filename).left(filenamelen);
                         emit onFileRemove(QString(filename).left(filenamelen));
                     break;
                     case FILE_ACTION_RENAMED_OLD_NAME:
                     qDebug() << "The FILE_ACTION_RENAMED_OLD_NAME" << QString(filename).left(filenamelen);
                         break;
                     case FILE_ACTION_RENAMED_NEW_NAME:
                      newDirName = QString(filename).left(filenamelen);
                      qDebug() << "The FILE_ACTION_RENAMED_NEW_NAME" << newDirName;
                        emit onDirRename(newDirName);
                         break;
                     default:
                         printf("\nDefault error.\n");
                         break;
                  }

                 //qDebug() << "pNotify->NextEntryOffset" << pNotify[offset].NextEntryOffset <<" offset "<< offset << nRet ;
                 offset += pNotify[offset].NextEntryOffset;
              }while(pNotify[offset].NextEntryOffset); //(offset != 0)
             ResetEvent(PollingOverlap.hEvent);
            }

          CloseHandle( DirInfo[0].hDir );


     }
 public:
 signals:
     void onDirRename(QString Dir);
     void onFileRemove(QString name);
     void onFileCopy(QString name);

 private:
 LPCWSTR path;
 typedef struct _DIRECTORY_INFO {
     HANDLE hDir;
     TCHAR lpszDirName[MAX_PATH];
     CHAR lpBuffer[MAX_BUFFER];
     DWORD dwBufLength;
     OVERLAPPED Overlapped;
  }DIRECTORY_INFO, *PDIRECTORY_INFO, *LPDIRECTORY_INFO;

 DIRECTORY_INFO DirInfo[MAX_DIRS];
 TCHAR FileList[MAX_FILES*MAX_PATH];
 DWORD numDirs;
 };

这是一个基于Qt的对象。路径是我将监视和更新任何更改的目录。

0 个答案:

没有答案