Saturday, June 7, 2014

Windows command line file/directory monitor

A windows command-line utility to monitor a given directory for changes and perform custom action. 
 

Introduction

To begin with, in this article I’m presenting a small windows command-line utility that i have developed in my leisure time.

Requirement: Time and again we feel the need of a windows command that could help us monitor changes in a directory and when a change is made, it could help us run a command or synchronize the changes to some other location or mail someone describing changes. I do have a similar need that led me develop this utility.

Possible Solutions: In windows there are two methods to monitor a directory for changes.
1> Timely poll directory/file modification time or size for any updation. This process is largely cpu intensive and is not a recommended option.
2> Use windows api (FindFirstChangeNotification) to hook for call-back events from OS for any changes made to directory in consideration.

Another Hurdle: I opted the second one. however in my case there was one more complexity. I want to listen to changes on a mounted network disk and in case of network disk, there is generally a limit on number of directories that you could monitor using above method. So though i need to monitor a huge directory but i need to optimally use the above method so as to remain in OS provided limit.

Final Solution: The way out was, even in a very huge directory, the chances of a file/directory getting modified is higher if the same has been modified recently. So if i could list all the files in directory under consideration in descending order by last modified time and listen to changes on top 50 files/directories, then more than 90% of changes would be covered. Off course there is a possibility of modification of a rarely modified file, but even then we can always re-sort the entire list and reselect files for monitoring. The utility implements the same logic.

Using the utility

So on the usage part. Here are the options:
FileWatcher: The program monitors selected directories within given
directory for any changes and runs the provided command if any changes
are made. The given command can contain %WDIR% and %UDIR%
tags, that would be subtituted with relative path of directories changed.
The directories to be monitored are selected based on last modified
files in given directory.
Options:
-d Directory  : Directory to be monitored
-c Command    : Command to execute when any file is modified
-h            : Prints this usage message
-q            : [Optional] Quite Mode
-v            : [Optional] Verbose
-t Timeout    : [Optional] Max Timeout in seconds to wait for
                directory changes. Default value is Infinite.
                Non-Infinite value is useful to accurately monitor
                rarly modified directories.
-m MaxCount   : [Optional] Maximum number of changes before reparsing
                whole tree for file modification times. Higher value
                saves initialization time for big directories but
                tradeoff accuracy. Default value is 1
-r Level      : [Optional] Maximum directory levels to look for files
                to be monitored. Default value is 0 => Infinite Levels.
-i Pattern    : [Optional] Only monitor name matching given regex.
-x Pattern    : [Optional] Don't monitor name matching given regex.
-w WatchCount : [Optional] Max directories to monitor. Default is 50
                value = 0=> as allowed by OS. Useful for remote folders

On the broader basis, the directory to be monitored and command to be executed are two required parameters. The command line can consist of following tags:
%WDIR%: This would be replaced by relative path of directory modified.
%UDIR%: Same as %WDIR%, but path separator used would be of Unix.

As an optional parameters max time (in seconds) to wait for directory changes can be specified along with "-t" option. This is particularly useful to cater cases where there is a huge directory and utility is listening for change events on only recently modified files, but a rarely modified file is updated.

The default behaviour of the utility is, after each identified change it reparses the given directory and reselect the files(based on their modification time) to be monitored subsequently. However parsing huge directories could be a time consuming operation, so with "-m" option, we can specify minimum number of contiguous directory change events to listen only after which reparsing would be done.

"-r" let us specify max depth in given directory to monitor for changes, "-i" and "-w" regular expression patterns for file paths to include and exclude respectively.

As earlier specified on network drives there is a restriction on number of directories that can be monitored for changes simultaneously, so if we use this utility on a huge network directory we could end up this limit and other programs would start starving for that. "-w" option let us specify a sublimit for this tool.

Downloads

https://code.google.com/p/file-watcher/

 

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv2)