Anwendung ReadDirectoryChangesW
Posted: Fri Nov 05, 2010 3:16 pm
				
				Hello,
sorry for that mistake. I've forget in which forum I am. 
 
And sorry for my bad following english.
The following code can be used to get notification on changes in a directory. In contrast to the FindFirstChangeNotification function I used ReadDirectoryChangesW. This has the benefit, that I can get the name of the changed element.
  Attention:Please set under compiler settings "Create unicode executable". Without that setting the filename isn't displayed correctly.
 Attention:Please set under compiler settings "Create unicode executable". Without that setting the filename isn't displayed correctly.
Ok, let us begin with a few definitions. The following constants are for building the filter setting for the function. With the filter you can define the behaviour of your notification.
This constant is also useful. It is often used in combination with the CreateFile function (that we need later).
With the ReadDirectoryChangesW you can request the action that happed to the given item. The following enum gives you the existing actions that can occure.
At next we need a Structure the ReadDirectoryChanges function can fill with information. After calling the function you can retrieve the filename from the structure and the actions that has taken place. The FieldNameLenght gives you the length for Unicode (5 letters -> FilenameLength=10)
The ReadDirectoryChangesW function is not defined in PureBasic (or I didn't found it). The workaround is a prototype. I also define a variable with the type of the defined prototype (for later use).
Ok, definitions are made. Now let us come to the function that you can use or customize (for productive use).
Example call
Have fun with it!
			sorry for that mistake. I've forget in which forum I am.
 
 And sorry for my bad following english.
The following code can be used to get notification on changes in a directory. In contrast to the FindFirstChangeNotification function I used ReadDirectoryChangesW. This has the benefit, that I can get the name of the changed element.
 Attention:Please set under compiler settings "Create unicode executable". Without that setting the filename isn't displayed correctly.
 Attention:Please set under compiler settings "Create unicode executable". Without that setting the filename isn't displayed correctly.Ok, let us begin with a few definitions. The following constants are for building the filter setting for the function. With the filter you can define the behaviour of your notification.
Code: Select all
; dwNotifyFilter values
#FILE_NOTIFY_CHANGE_FILE_NAME = 1
#FILE_NOTIFY_CHANGE_DIR_NAME = 2
#FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
#FILE_NOTIFY_CHANGE_SIZE = 8
#FILE_NOTIFY_CHANGE_LAST_WRITE = $10
#FILE_NOTIFY_CHANGE_LAST_ACCESS = $20
#FILE_NOTIFY_CHANGE_CREATION = $40
#FILE_NOTIFY_CHANGE_SECURITY = $100
Code: Select all
#FILE_SHARE_DELETE = 4Code: Select all
Enumeration
  #FILE_ACTION_ADDED = 1
  #FILE_ACTION_REMOVED
  #FILE_ACTION_MODIFIED
  #FILE_ACTION_RENAMED_OLD_NAME
  #FILE_ACTION_RENAMED_NEW_NAME
EndEnumeration
Code: Select all
; Notify info structure
Structure FILE_NOTIFY_INFORMATION
  NextEntryOffset.l
  Action.l
  FileNameLength.l
  Filename.s{255}
EndStructure
Code: Select all
Prototype.b _ReadDirectoryChangesW(hDirectory.l, *lpBuffer,nBufferLength.l,bWatchSubtree.b,dwNotifyFilter.l,*lpBytesReturned,*lpOverlapped.OVERLAPPED,lpCompletionRoutine)
Define ReadDirectoryChangesW._ReadDirectoryChangesWCode: Select all
Procedure WatchDirOrFile(name$, filter.l = #FILE_NOTIFY_CHANGE_CREATION|#FILE_NOTIFY_CHANGE_LAST_ACCESS|#FILE_NOTIFY_CHANGE_DIR_NAME)
  Shared ReadDirectoryChangesW
  
  ; allocate buffer for results
  Define *buffer.FILE_NOTIFY_INFORMATION = AllocateMemory(SizeOf(FILE_NOTIFY_INFORMATION))
  Define ovlp.OVERLAPPED
  Define ReadDirectoryChangesW._ReadDirectoryChangesW  
  
  If Not ReadDirectoryChangesW
    *kernel32dll = OpenLibrary(#PB_Any,"kernel32.dll")
    ReadDirectoryChangesW = GetFunction(*kernel32dll,"ReadDirectoryChangesW")
  EndIf
    
  ; get handle to directory
  hDir = CreateFile_(name$,#FILE_LIST_DIRECTORY,#FILE_SHARE_READ|#FILE_SHARE_WRITE|#FILE_SHARE_DELETE,#Null,#OPEN_EXISTING,#FILE_FLAG_BACKUP_SEMANTICS,#Null)
  
  While ReadDirectoryChangesW(hDir,*buffer,SizeOf(FILE_NOTIFY_INFORMATION),#True,filter,bytesRead,ovlp,0) 
    Debug *buffer\Action
    Debug *buffer\FileNameLength
    
    Select *buffer\Action
      Case #FILE_ACTION_ADDED
      Case #FILE_ACTION_REMOVED
      Case #FILE_ACTION_MODIFIED
        Debug *buffer\Filename + " wurde modifiziert"
      Case #FILE_ACTION_RENAMED_OLD_NAME
      Case #FILE_ACTION_RENAMED_NEW_NAME
        
    EndSelect
        
    FreeMemory(*buffer)
    *buffer.FILE_NOTIFY_INFORMATION = AllocateMemory(SizeOf(FILE_NOTIFY_INFORMATION))
  Wend
EndProcedureExample call
Code: Select all
WatchDirOrFile(GetCurrentDirectory())