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.
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.

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 = 4
Code: 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._ReadDirectoryChangesW
Code: 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
EndProcedure
Example call
Code: Select all
WatchDirOrFile(GetCurrentDirectory())