pyscripter 826 Posted Tuesday at 04:47 PM (edited) Whilst there are many Delphi components for detecting changes to file system folders they suffer from serious limitations: typically they only allow you to monitor a single folder they do not support the monitoring of specific files they rely on the FindFirstChangeNotification API which gives no information about what has changed, requiring an inefficient search. I have created a new file system monitoring library that addresses the above limitations. Features: Easy to use, but also suitable for heavy duty monitoring Single unit with no external dependencies Allows monitoring folders and/or specific files Uses the ReadDirectoryChangesW API which provides information about what exactly was changed A single instance of the component can handle the monitoring of many folders and/or files Uses an I/O completion port for efficient handling of large numbers of requests A single thread handles all requests A different notification handler can be specified for each request You can have multiple handlers for each folder or file When you monitor folders you can specify whether you want to also monitor subfolders Installation: You do not need to install the library. Just download or clone the repo and add the source subdirectory to the Library path. Usage: procedure TForm1.FormCreate(Sender: TObject); begin // Create the IFileSystemMonitor interface FFileSystemMonitor := CreateFileSystemMonitor; // Monitor a directory FFileSystemMonitor.AddDirectory(TPath.GetTempPath, False, HandleChange); // Also monitor a specific file FFileSystemMonitor.AddFile('pathtoyourfile', HandleChange); end; procedure TForm1.HandleChange(Sender: TObject; const Path: string; ChangeType: TFileChangeType); begin with lvEventList.Items.Add do begin Caption := GetEnumName(TypeInfo(TFileChangeType), Integer(ChangeType)); SubItems.Add(Path); end; end; To stop monitoring a specific file or folder you use the following methods: function RemoveDirectory(const Directory: string; OnChange: TMonitorChangeHandler): Boolean; function RemoveFile(const FilePath: string; OnChange: TMonitorChangeHandler): Boolean; Edited Tuesday at 09:22 PM by pyscripter 17 11 Share this post Link to post
Tommi Prami 157 Posted yesterday at 03:55 AM (edited) Very nice. Way better than constant polling for sure. I think I have no use for this now, but have to think about it, maybe I can think of something. In previous live used FindFirstChangeNotification API, did not knoew that there is other API for this. -Tee- Edited yesterday at 04:23 AM by Tommi Prami typo Share this post Link to post
Dave Novo 57 Posted yesterday at 07:09 PM Thanks for all the amazing work you do and contribute to the community! Share this post Link to post
mjustin 31 Posted 12 hours ago Sorry for asking, but is polling still necessary if the monitoring application (which uses IFileSystemMonitor) was not running for a while, and during that time changes happened? Or does IFileSystemMonitor provide ways to detect changes which happened while it was "absent"? Share this post Link to post
M.e.l 1 Posted 11 hours ago Hi, It looks simple and good. Does it work across network or VPN ? i.e. can a server directory be monitored from an app running your monitoring class on a client PC, connected to the server through network ? Mel Share this post Link to post
Anders Melander 2060 Posted 10 hours ago 38 minutes ago, M.e.l said: Does it work across network or VPN ? i.e. can a server directory be monitored from an app running your monitoring class on a client PC, connected to the server through network ? VPN is just transport layer encryption and is not relevant. The documentation for ReadDirectoryChangesW answers your other question: Quote If the network redirector or the target file system does not support this operation, the function fails with ERROR_INVALID_FUNCTION. Quote In Windows 8 and Windows Server 2012, this function is supported by the following technologies. Technology Supported Server Message Block (SMB) 3.0 protocol Yes SMB 3.0 Transparent Failover (TFO) Yes SMB 3.0 with Scale-out File Shares (SO) Yes Cluster Shared Volume File System (CsvFS) Yes Resilient File System (ReFS) Yes Share this post Link to post
pyscripter 826 Posted 10 hours ago @mjustin Have a look at the source code. https://github.com/pyscripter/FileSystemMonitor/blob/2dd27a0570ae2f839acb9de3bf67bb2247893784/Source/FileSystemMonitor.pas#L415C16-L415C41 All the thread does is wait on the I/O complection port using GetQueuedCompletionStatus. This function blocks until a change happens. The only polling that takes place is to check every 5 seconds, for deletion/rename of the monitored directories themselves, which are not reported by ReadDirectoryChanges. Folders can be attached to/detached from the completion port at any time, without any problem. Share this post Link to post
Anders Melander 2060 Posted 9 hours ago 41 minutes ago, pyscripter said: deletion/rename of the monitored directories themselves, which are not reported by ReadDirectoryChanges. ...unless you also monitor the parent directory. Maybe make the polling optional? 1 Share this post Link to post
pyscripter 826 Posted 8 hours ago (edited) 1 hour ago, Anders Melander said: ...unless you also monitor the parent directory. You will still have the same issue if the parent directory (or the parent of the parent...) gets deleted or renamed. Even if it is not, you may be getting many more notifications than you need. Also you would have to watch subfolders, which you may not want. It is not worth it. Checking every x seconds whether the monitored directories still exist is a tiny overhead. Edited 8 hours ago by pyscripter Share this post Link to post