2

Je suis en train de suivre un répertoire e:\test en utilisant l'API ReadDirectoryChangesW.répertoire de surveillance en utilisant l'API ReadDirectoryChangesW

Mon code:

#define UNICODE 
#define WIN32_WINNT 0x0500 
#include "stdafx.h" 
#include <stdio.h> 
#include <windows.h> 


HANDLE hDir; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    FILE_NOTIFY_INFORMATION fniDir; 
    DWORD i = 0; 

    hDir = CreateFile(_T("e:\\test"), GENERIC_READ , FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 

    ReadDirectoryChangesW(hDir, &fniDir, sizeof(fniDir), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME, &i, NULL, NULL); 
    while(TRUE) 
    { 


    if(i>0) 
     wprintf(L"%s", fniDir.FileName); 
    } 

    CloseHandle(hDir); 

    return 0; 
} 

Je ne sais pas quel est le problème avec mon code comme je l'ai pas compris la documentation ReadDirectoryChangesW complètement, spécialement les paramètres LPOVERLAPPED.

Quand je lance le code que je ne reçois pas de sortie, à l'exception d'une fenêtre de la console vide. Quelqu'un peut-il me diriger dans une bonne direction?

Merci.

Répondre

8

Vous avez seulement besoin struct chevauchée si vous prévoyez attraper les notifications de changements de manière asynchrone. Dans votre code, vous n'en avez pas besoin.

Voici comment vous le faites.

HANDLE hDir = CreateFile( 
     p.string().c_str(), /* pointer to the file name */ 
     FILE_LIST_DIRECTORY,    /* (this is important to be FILE_LIST_DIRECTORY!) access (read-write) mode */ 
     FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, /* (file share write is needed, or else user is not able to rename file while you hold it) share mode */ 
     NULL, /* security descriptor */ 
     OPEN_EXISTING, /* how to create */ 
     FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */ 
     NULL /* file with attributes to copy */ 
     ); 

    if(hDir == INVALID_HANDLE_VALUE){ 
     throw runtime_error(string("Could not open ").append(p.string()).append(" for watching!")); 
    } 

    FILE_NOTIFY_INFORMATION buffer[1024]; 
    DWORD BytesReturned; 
    while(ReadDirectoryChangesW(
     hDir, /* handle to directory */ 
     &buffer, /* read results buffer */ 
     sizeof(buffer), /* length of buffer */ 
     TRUE, /* monitoring option */   
     FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */ 
     &BytesReturned, /* bytes returned */ 
     NULL, /* overlapped buffer */ 
     NULL)){ 
      do{ 
          //CANT DO THIS! FileName is NOT \0 terminated 
       //wprintf("file: %s\n",buffer.FileName); 
          buffer += buffer.NextEntryOffset; 
      }while(buffer.NextEntryOffset); 
    } 
+0

+1 Merci pour votre réponse. J'ai quelques questions Pourquoi devons-nous créer une matrice de 'FILE_NOTIFY_INFORMATION' et ce qui est' NextEntryOffset'-t-il dire qu'il contient le nombre d'octets pour aller enregistrement suivant dans le tableau? – Searock

+0

@Searock Une notification peut contenir plus d'un fichier modifié dans ce répertoire. Vous ne recevez pas une notification par changement mais des lots. Le tampon y est parce que FILE_NOTIFIY_INFORMATION utilise définit le nom de fichier comme wchar un « tour » [1] (http://msdn.microsoft.com/en-us/library/aa364391%28v=vs.85%29.aspx) et alors vous êtes responsable de le régler à une taille correspondant au nombre de fichiers dont vous avez besoin. – RedX

+1

Le code d'itération du tampon est incorrect. Chaque membre de structure FILE_NOTIFY_INFORMATION est de longueur variable, donc vous ne pouvez pas simplement indexer dans le tableau. Vous devez calculer la distance à l'entrée suivante à chaque fois. En outre, wprintf est incorrect. FileName n'est pas terminé par null. –

Questions connexes