WaitForMultipleObjects: Verhalten abhängig von Timeout



  • Hallo,

    ich spiele gerade mit ReadDirectoryChangesW herum, im Kontext von Windows 7 Home 64-Bit und VS 2010.
    Ich nutze ReadDirectoryChangesW mit Overlapped um asynchron die Ergebnisse zu bekommen. Darauf, dass es fertig ist, warte ich mit WaitForMultipleObjects. Spezifiziere ich als Timeout INFINITE, funktioniert alles - bei einem Timeout von 20 oder 50 ms kommt nur Mist: FILE_NOTIFY_INFORMATION ist dann immer gesetzt mit

    NextEntryOffset = 0
    Action = FILE_ACTION_MODIFIED
    FileNameLength = 12
    FileName = Korrekter Pfad zu Datei oder Ordner
    

    Ich kann es wirklich nicht nachvollziehen. Hier mal ein kleiner lauffähiger Beispielcode in C++:

    #include <Windows.h>
    #include <iostream>
    #include <string>
    
    const std::wstring DIRECTORY = L"C:\\Users\\BenutzerXY\\Desktop";
    
    int main() {
    	HANDLE DirectoryHandle = CreateFile( DIRECTORY.c_str(), FILE_LIST_DIRECTORY|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL );
    	if(DirectoryHandle==INVALID_HANDLE_VALUE)  std::cout<<"Could not open directory!\n";
    
    	OVERLAPPED ov;
    	memset( &ov, 0, sizeof(ov) );
    	ov.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    
    	char Buffer[3000];
    	std::wstring OldName;
    	while ( true ) {
    		DWORD Written;
    		BOOL Result = ReadDirectoryChangesW( DirectoryHandle, Buffer, sizeof(Buffer), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &Written, &ov, NULL );
    		if( ! Result )
    			std::cout << "ReadDirectoryChanges failed!\n";
    
    		if ( WaitForMultipleObjects( 1, &ov.hEvent, FALSE, 20 ) == WAIT_OBJECT_0 ) {
    			FILE_NOTIFY_INFORMATION* fni = (FILE_NOTIFY_INFORMATION*)&Buffer[0];
    			for ( ; ; ) {
    				switch ( fni->Action ) {
    					case FILE_ACTION_ADDED:
    						std::cout << "FILE_ACTION_ADDED\n";
    						break;
    					case FILE_ACTION_REMOVED:
    						std::cout << "FILE_ACTION_REMOVED\n";
    						break;
    					case FILE_ACTION_MODIFIED:
    						std::cout << "FILE_ACTION_MODIFIED\n";
    						break;
    					case FILE_ACTION_RENAMED_OLD_NAME:
    						std::cout << "FILE_ACTION_RENAMED_OLD_NAME\n";
    						break;
    					case FILE_ACTION_RENAMED_NEW_NAME:
    						std::cout << "FILE_ACTION_RENAMED_NEW_NAME\n";
    						break;
    					default:
    						std::cout << "ReadDirectoryChanges, unknown action\n";
    						break;
    				}
    				if ( fni->NextEntryOffset == 0 )
    					break;
    				fni = (FILE_NOTIFY_INFORMATION*)( ((char*)fni) + fni->NextEntryOffset );
    			}
    		}
    	}
    
    	CloseHandle( ov.hEvent );
    	CloseHandle( DirectoryHandle );
    }
    


  • Ok, geht jetzt, ich musste noch ein GetOverlappedResult dazwischensetzen 🙂


Anmelden zum Antworten