ReadDirectoryChangesW Asynchron in einem Thread C++
-
Hallo Leute,
hat jemand ein Beispiel für ReadDirectoryChangesW in der Asynchronen Variante für mich? Ich beschäftige mich jetzt schon fast 2 Wochen mit dem Thema und komm irgendwie nicht weiter. In der Synchronen Variante funktioniert es soweit, lösche ich jedoch 2 Dateien gleichzeitig oder kopiere mehrere Dateien, kommt mein Dienst völlig aus dem Schritt und hängt sich auf.
Mein bisheriger Code:void __fastcall TWatchThread::Execute() { BOOL bResult; HANDLE hDir; BYTE Buf[32 * 1024]; DWORD RetBytes; FILE_NOTIFY_INFORMATION *pInfo; DWORD i = 0; WCHAR FileName[1000]; DWORD bufSize = 32000;//sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH*sizeof(WCHAR); hDir = CreateFile( FWatchPath.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL); AnsiString strActionMsg; while(!Terminated)//(true) { bResult = ReadDirectoryChangesW( hDir, Buf, bufSize,//10000, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME // Löschen, Erstellen oder Umbenennen | FILE_NOTIFY_CHANGE_DIR_NAME // Löschen oder Erstellen oder Umbenennen eines Verzeichnisses | FILE_NOTIFY_CHANGE_SIZE // Größe ändert sich | FILE_NOTIFY_CHANGE_LAST_WRITE // Dateizeit Letzte Änderung | FILE_NOTIFY_CHANGE_ATTRIBUTES // Attribute geändert | FILE_NOTIFY_CHANGE_LAST_ACCESS // Dateizeit Letzter Zugriff (auch Lesen) | FILE_NOTIFY_CHANGE_CREATION // Dateizeit Erstellungsdatum ändert sich | FILE_NOTIFY_CHANGE_SECURITY, &RetBytes, NULL, NULL); if(bResult != 0) { for(;;) { Beep(500, 200); strActionMsg = ""; pInfo = (FILE_NOTIFY_INFORMATION *)&Buf[i]; switch(pInfo->Action) { case FILE_ACTION_ADDED: strActionMsg = "file added: "; break; case FILE_ACTION_REMOVED: strActionMsg = "file deleted: "; break; case FILE_ACTION_MODIFIED: strActionMsg = "time stamp or attribute changed: "; break; case FILE_ACTION_RENAMED_OLD_NAME: strActionMsg = "file name changed - old name: "; break; case FILE_ACTION_RENAMED_NEW_NAME: strActionMsg = "file name changed - new name: "; break; default: strActionMsg = "unknown event: "; };//switch DateiListe->Add(strActionMsg + FWatchPath + "\\" + AnsiString(((FILE_NOTIFY_INFORMATION*) pInfo)->FileName)); if(pInfo->NextEntryOffset == 0) { break; }//if else { i = i + pInfo->NextEntryOffset; }//else }//for DateiListe->SaveToFile("C:\\Temp\\DateiListe.txt"); }//if }//while CloseHandle(hDir); }Es soll eine Dienstanwendung werden, die die Änderungen in eine Datenbank schreibt. Zum Testen lass ich mir das aber erstmal in ein Textfile schreiben. Das Beep() zeigt mir akustisch an, wann der Dienst was macht. Ändere ich einzelne Dateien, kommt auch immer schön 1-2 beeps. Ändere ich mehrere Dateien, peeps es noch ein paar mal und dann ist ende.
Bitte helft mir

mfg Stephan
-
Das ist Dir bekannt?
http://support.microsoft.com/kb/245214Und was ist Dein Problem?
Defniere den OVERLAPPED Buffer mit dem Event Handle.Dann den RDCW normal ausführen. Die Funktion kehrt zurück.
Nun kannst Du das Event benutzen und warten, das etwas eintrudelt.
GetOverlapedResult aufrufen und Daten wegpacken.Aber wenn Du immer sofort die Datei schreibst, dann blockierst Du ja förmlich.
Du speicherst die ganze Liste immer neu, oder wie?Kontrollierst Du Fehler von RDCW? Nein! Nicht gut...
Es gibt massenweise Codesamples:
http://www.codeproject.com/file/directorychangewatcher.aspMSDN-SDK Samples: Fwatch
IMHO aber nur in älteren SDKs dabei.
-
Schau Dir mal den Code an:
http://web.cecs.pdx.edu/~quisling/ftproot/DirMonitor/
-
Hallo Martin,
danke für deine Antwort.
zu dem Link zu Microsoft: gibts den Text auch in Deutsch?
die schlimmste Übersetzung die ich bisher gesehen hab. Das Zielsystem ist Win2k3, sollte hier also nicht zutreffen.Das Beispiel von CodeProject.com habe ich mir schon angeschaut. Es ist leider etwas zu kompliziert für mich. Ich arbeite mit BCB6 und kann das Beispiel bei mir nicht einbinden, da es für VC++ ist. Ich habe versucht den Code zu verstehen, aber musste da leider kapitulieren. Ich habe es einfach nicht geschafft dieses Beispiel einer Gui-Anwendung auf meine kleine Serviceanwendung umzumünzen. Ich schau mir mal das andere Beispiel an, das du gelinkt hast und melde mich später wieder.
mfg Stephan