Desaware Home
Products    Purchase    Publishing    Articles   Support    Company    Contact    
Articles
.NET
COM

 

 

bluebar
Contact Desaware and order today

bluebar
Sign up for Desaware's Newsletter for the latest news and tech tips.

Monitoring file changes

A popular function developers are implementing these days consists of monitoring a system for changes to files. This feature can be used to detect situations where viruses modify your system files, or web sites add cookies and other files to your system. It can also be used to notify you that a shared file has been updated and the changes need to be reviewed.

This article will discuss monitoring for file changes in Visual Basic 6.0 using the FindFirstChangeNotification API function. The parameters passed to the function describe the folder you want to monitor, whether to monitor the folder's subfolders, and the type of file changes to detect. You can also use the FindNextChangeNotification API function to continue monitoring the folder after you have detected a file change, and the FindCloseChangeNotification API function to stop monitoring the folder. The sample code below demonstrates monitoring the Windows folder for file changes.

Private Declare Function FindFirstChangeNotification _
Lib "kernel32" Alias "FindFirstChangeNotificationA" _
(ByVal lpPathName As String, ByVal bWatchSubtree As Long, _
ByVal dwNotifyFilter As Long) As Long

Private Const FILE_NOTIFY_CHANGE_FILE_NAME = &H1
Private Const FILE_NOTIFY_CHANGE_ATTRIBUTES = &H4
Private Const FILE_NOTIFY_CHANGE_LAST_WRITE = &H10

m_WaitHandle = FindFirstChangeNotification("C:\Windows", _
   False, FILE_NOTIFY_CHANGE_LAST_WRITE _
   Or FILE_NOTIFY_CHANGE_FILE_NAME Or _
   FILE_NOTIFY_CHANGE_ATTRIBUTES)

The FILE_NOTIFY_CHANGE_FILE_NAME flag requests detection of file name changes including renaming, creating, or deleting a file name. The FILE_NOTIFY_CHANGE_LAST_WRITE flag requests notification when a file is written to the disk. The FILE_NOTIFY_CHANGE_ATTRIBUTES flag requests notification when a file's attributes have changed (such as resetting the file's ReadOnly attribute). Other file change flags available for use include FILE_NOTIFY_CHANGE_DIR_NAME which detects folder name changes, FILE_NOTIFY_CHANGE_SIZE which detects changes in the file's size (this is covered by the FILE_NOTIFY_CHANGE_LAST_WRITE flag), and FILE_NOTIFY_CHANGE_SECURITY which detects changes to a file's security descriptor.

There are two obstacles to using the FindFirstChangeNotification API function. One challenge is that the FindFirstChangeNotification API function returns a wait handle on success, meaning you need to call an additional API function such as WaitForSingleObject and wait for that function to return before your program can continue.

If m_WaitHandle <> -1 Then
   Do
      DoEvents
      result = WaitForSingleObject(m_WaitHandle, 50)
   Loop
End If

The WaitForSingleObject function will not return until after a file change has been detected or after a specified timeout has elapsed (in the sample code above, 50 milliseconds). You should either run the code calling the WaitForSingleObject function in a background thread so as not to freeze your application while waiting for a file change, or use a small timeout value within an infinite loop and call DoEvents to allow your application to do some processing while waiting (as demonstrated above).

The second challenge is that once a file change has been detected, there is no information provided on which file was changed. Unless the folder you are monitoring contains just a single file, you would need to take a snapshot of the folder you are monitoring, then compare the snapshot information with the current information for all the files when the WaitForSingleObject function returns in order to determine which file has changed.

One possible implementation of this is to enumerate the folder being monitored and retrieve all the file information prior to starting the monitor. Place all of this information in a collection. When a file change occurs, compare the collection with the existing list of files to determine which file has changed. Note that only a single file change will occur each time the WaitForSingleObject function returns. You can check for the following cases.

  1. If an enumerated file's attributes, date/time stamp, size have changed, it indicates that the file was changed.
  2. If an enumerated file was not found in the snapshot collection, it indicates that the file was newly added to the folder.
  3. If a file in the snapshot collection was not compared to the enumerated file list, it indicates that the file was deleted from the folder.
  4. If both cases 2 and 3 occurred, it indicates that the file was renamed.

You can implement this functionality in a standard Visual Basic 6 application. You can launch a background thread and call the WaitForSingleObject function inside the background thread (without any timeout which will suspend the background thread until a file change occurs) or use an infinite loop with a call to the WaitForSingleObject function inside the infinite loop. Continuously calling the WaitForSingleObject function inside the infinite loop will use up some CPU processing time, but you can adjust the timeout value to minimize the impact on your system. Desaware's background thread component (dwbackthread) is ideal for implementing waits inside a background thread using Visual Basic 6. Finally, this type of file monitoring is typically done through a Windows Service. Services are ideal for running background operations that waits for events to occur. Implementing this in a Service allows you to efficiently create multiple background threads to monitor different folders concurrently. Desaware's NT Service Toolkit allows you to implement this within a service and includes a sample project demonstrating this.

For notification when new articles are available, sign up for Desaware's Newsletter.

articles
Related Products:
 
Products    Purchase    Articles    Support    Company    Contact
Copyright© 2012 Desaware, Inc. All Rights Reserved.    Privacy Policy