Spy on a Folder to Detect When it Change
Ever need to know when the contents of a folder have changed? Using the
FindFirstChangeNotification and FindNextChangeNotification
functions you can have Windows alert your application whenever a folder or any
of its sub-folders change. Changes detected include copying, deleting,
renaming files as well as changing the size or attributes of any files in the
folder or in any sub folders!
This sample also shows how to suspend your application's processing until
multiple events have occurred. In this case I wait for a folder to change
or a program to terminate. The WaitForMultipleObjects
function makes this possible.
Download Source Code
This VB6 program uses the FileSystemObject from the
Microsoft Scripting Runtime Engine (Scrrun.dll) to display the number of files
in a folder. Scrrun.dll comes with VB6 and Windows 98 or later (see my
Using the FileSystemObject sample for more info).
If you don't have this dll comment out the lines containing "FSO" and uncheck
the "Microsoft Scripting Runtime" entry in the
Project | References dialog.
The Folder Spy program detects changes occurring in a folder by calling the
FindFirstChangeNotification API.. Then using the
WaitForSingleObject function it waits until Windows notifies it that
a change has occurred. The advantage of using WaitForSingleObject
is that the program enters a very efficient wait state (it consumes very little
CPU resources) until notified of a change.
WaitForSingleObject lets you specify the amount of
time to wait. It can be infinite or a relatively long period. The
down side is that the program is completely frozen and will not respond to
mouse events until the folder changes. If no changes occur, the program
will be frozen forever! See my Wait for Process
to Terminate example for more info.
To overcome this the wait function is placed in a loop and the time interval is
set to a small value. When the function completes its return code is
tested. If it returned because the object being waited for was
signaled (i.e. the folder changed) the loop terminates. Otherwise a
DoEvents is issued so the program can react to mouse or other events and the
wait function is re-executed.
When the folder changes a message is displayed and the FindNextChangeNotification
function is used to detect subsequent changes. Phew!
Okay, I lied. I don't use WaitForSingleObject.
I use WaitForMultipleObjects lets you wait for
more than one thing. When the program starts spying it launches a small
executable ("Stop Spy" shown on the left in the above picture). The Stop
Spying executable does nothing except display a button that terminates it when
clicked. WaitForMultipleObjects lets Folder
Spy wait until either Stop Spy ends or the folder changes. Since Stop Spy
runs separately from the main program it is not effected by the wait function
and is always responsive to mouse events. When WaitForMultipleObjects
terminates its return code is checked. If it returned because the folder
changed, a message is displayed.
What happens to the Stop Spy executable when you click the Quit button? It
gets terminated. Briefly, to kill it all top level windows are enumerated
to create a list of those owned by the process whose ID matches that of the
Stop Spy executable. Then a WM_CLOSE message
is sent to those windows causing the .exe to end. This is discussed
further in my Safely Stop a Running Process
Confused? Download the code and play with it. It is really straight
Download the program, press F5 to run it, enter a valid path then click the
"Start Spying" button.
Open Explorer and navigate to the folder you are spying on. Arrange
Explorer and FolderSpy so both programs are visible. Make changes to the
folder by copying or deleting a file or by changing the attributes for a file
(right click the file and select properties). As soon as a change is
made, FolderSpy will alert you with a message.
Try clicking the "Stop Spying" or "Quit" buttons and you will see that FolderSpy
does not react until the wait period expires. Experiment with different
wait periods in function fWaitForChange to see the effect.
Now run Folder Spy again and click the "Stop Spying on Folder" button on the
Stop Spying form. You will see that this causes FolderSpy to immediately
stop waiting and start responding to your input again.