Having problems with your account or logging in?
A lot of changes are happening in the community right now. Some may affect you. READ MORE HERE

Using FileSystemWatcher class to monitor a folder in .NET

Using FileSystemWatcher class to monitor a folder in .NET

FileChangeNotifierVC.zip

Problem:

Is it possible to monitor a specified folder or filename for any changes that may occur from within a Visual COBOL Windows Forms application?

Resolution:

Yes it is possible to monitor either a specified folder or filename for any changes and to fire an event when a change does occur by using the .NET System.IO.FileSystemWatcher class in conjunction with a timer event.

There is a demo program attached to this article called FileChangeNotifierVC.zip. Please unzip this to your computer retaining the folder structure in the zip file. Open up the FileChangeNotifierVC.sln file in Visual COBOL for Visual Studio 2.2 update 2 or higher. This is a Windows Forms application that will monitor the file system for changes to a specified folder or filename and will report those changes in a ListBox control on the form.

The contents of the main form program are shown below:

   
*---------------------------------------------------
*                        FileChangeNotifierVC Demo 
*                                                 
*  This sample program will demonstrate how a file or folder can be 
*  monitored from within a Windows Forms application in Visual COBOL 
*  2.2 update 2 or higher. A form will be displayed allowing the user 
*  to specify whether a file or folder should be monitored and whether 
*  subfolders should also be included. When the User clicks on the 
*  Start Watch button the application will instantiate an object of
*  type FileSystemWatcher and set it to monitor the selected criteria 
*  and will set up event handlers to be fired whenever a file or folder 
*  is updated. When an update does occur the event handlers will format 
*  and display the details of the update to a listbox on the form. 
*  A timer event is fired every 100 ms in order to check if an update 
*  has occurred.
*    
*  There is also a log button that will allow you to save the contents 
*  of the listbox to a text file.
*----------------------------------------------------
$set ilusing"System"
$set ilusing"System.Collections.Generic"
$set ilusing"System.ComponentModel"
$set ilusing"System.Data"
$set ilusing"System.Drawing"
$set ilusing"System.Text"
$set ilusing"System.Windows.Forms"
$set ilusing"System.IO"

 class-id FileChangeNotifierVC.FormMain is partial
          inherits type System.Windows.Forms.Form.
 working-storage section.
 01 m_Sb type StringBuilder.
 01 m_bDirty condition-value.
 01 m_Watcher type FileSystemWatcher.
 01 m_bIsWatching condition-value.
 method-id NEW.
 procedure division.
    invoke self::InitializeComponent()
    set m_Sb to new StringBuilder
    set m_bDirty to false
    set m_bIsWatching to false.
           
 end method.

* This method is invoked whenever a timer event occurs which is set 
* for every 100 ms. When a change has been detected then it will add 
* the details to the listbox.
* 
 method-id tmrEditNotify_Tick final private.
 procedure division using by value sender as object e as type System.EventArgs.
       
    if m_bDirty
       invoke lstNotification::BeginUpdate
       invoke lstNotification::Items::Add(m_Sb::ToString)
       invoke lstNotification::EndUpdate
       set m_bDirty to false
    end-if.
           
 end method.

* This method is called whenever the Start Watch or Stop Watch button 
* is clicked. Depending on the current state of the button it will 
* either setup the FileSystemWatcher events or disable them.
*
 method-id btnWatchFile_Click final private.
 procedure division using by value sender as object e as type System.EventArgs.
       
    if m_bIsWatching
       set m_bIsWatching to false
       set m_Watcher::EnableRaisingEvents to false
       invoke m_Watcher::Dispose
       set btnWatchFile::BackColor to type Color::LightSkyBlue
       set btnWatchFile::Text to "Start Watching"
    else
       set m_bIsWatching to true
       set btnWatchFile::BackColor to type Color::Red
       set btnWatchFile::Text to "Stop Watching"
       set m_Watcher to new System.IO.FileSystemWatcher
       if rdbDir::Checked
          set m_Watcher::Filter to "*.*"
          set m_Watcher::Path to txtFile::Text & "\"
       else
          set m_Watcher::Filter to txtFile::Text::Substring(txtFile::Text::LastIndexOf('\') + 1)
          set m_Watcher::Path to txtFile::Text::Substring(0, txtFile::Text::Length - m_Watcher::Filter::Length)
       end-if   
       if chkSubFolder::Checked
          set m_Watcher::IncludeSubdirectories to true
       end-if
              
       set m_Watcher::NotifyFilter to type NotifyFilters::LastAccess b-or type NotifyFilters::LastWrite
           b-or type NotifyFilters::FileName b-or type NotifyFilters::DirectoryName
       attach method OnChanged to m_Watcher::Changed
       attach method OnChanged to m_Watcher::Created
       attach method OnChanged to m_Watcher::Deleted
       attach method OnRenamed to m_Watcher::Renamed
       set m_Watcher::EnableRaisingEvents to true
   end-if.
           
 end method.

* Event Handler method invoked when a file or folder is Changed, 
* Created or Deleted. This will format the string with details of 
* the change and this will be added to the listbox in next timer 
* event by its event handler.
*
 method-id OnChanged public.
 procedure division using by value sender as object, e as type FileSystemEventArgs.
    if not m_bDirty
       invoke m_Sb::Remove(0, m_Sb::Length)
       invoke m_Sb::Append(e::FullPath)
       invoke m_Sb::Append(" ")
       invoke m_Sb::Append(e::ChangeType::ToString)
       invoke m_Sb::Append("    ")
       invoke m_Sb::Append(type DateTime::Now::ToString)
       set m_bDirty to true
    end-if.
 end method.

* Event Handler method invoked whenever a file or folder is Renamed.
* This will format the string with details of the change and this 
* will be added to the listbox in next timer event by its 
* event handler.
*
 method-id OnRenamed public.
 procedure division using by value sender as object, e as type RenamedEventArgs.
    if not m_bDirty
       invoke m_Sb::Remove(0, m_Sb::Length)
       invoke m_Sb::Append(e::OldFullPath)
       invoke m_Sb::Append(" ")
       invoke m_Sb::Append(e::ChangeType::ToString)
       invoke m_Sb::Append(" ")
       invoke m_Sb::Append("to ")
       invoke m_Sb::Append(e::Name)
       invoke m_Sb::Append("    ")
       invoke m_Sb::Append(type DateTime::Now::ToString)
       set m_bDirty to true
       if rdbFile::Checked
          set m_Watcher::Filter to e::Name
          set m_Watcher::Path to e::FullPath::Substring(0, e::FullPath::Length - m_Watcher::Filter::Length)
       end-if
   end-if.
       
 end method.

* Event Handler fired whenever the Log button is clicked. 
* This will allow user to specify a filename into which the 
* listbox details will be written.
*
 method-id btnLog_Click final private.
 procedure division using by value sender as object e as type System.EventArgs.
           
    declare resDialog as type DialogResult = dlgSaveFile::ShowDialog
    if resDialog::ToString = "OK"
       declare fi as type FileInfo = new FileInfo(dlgSaveFile::FileName)
       declare sw as type StreamWriter = fi::CreateText
       perform varying sItem as string thru lstNotification::Items
          invoke sw::WriteLine(sItem)
       end-perform
       invoke sw::Close
    end-if.
           
 end method.

* Event Handler fired whenever the browse to file or folder name 
* button is clicked allow the user to select the folder name or 
* the filename to monitor.
*
 method-id btnBrowseFile_Click final private.
 procedure division using by value sender as object e as type System.EventArgs.
       
    if rdbDir::Checked
       declare resDialog as type DialogResult = dlgOpenDir::ShowDialog
       if resDialog::ToString = "OK"
          set txtFile::Text to dlgOpenDir::SelectedPath
       end-if
    else
       declare resDialog as type DialogResult = dlgOpenFile::ShowDialog
       if resDialog::ToString = "OK"
          set txtFile::Text to dlgOpenFile::FileName
       end-if
    end-if.
           
 end method.

* Event Handler fired whenever the radio button for Watch 
* Files changes state.
*
 method-id rdbFile_CheckedChanged final private.
 procedure division using by value sender as object e as type System.EventArgs.
    if rdbFile::Checked = true
       set chkSubFolder::Enabled to false
       set chkSubFolder::Checked to false
    end-if.
                       
 end method.

* Event Handler fired whenever the radio button for Watch 
* Folders changes state.
*
 method-id rdbDir_CheckedChanged final private.
 procedure division using by value sender as object e as type System.EventArgs.
       
    if rdbDir::Checked = true
       set chkSubFolder::Enabled to true
    end-if
            
 end method.

 end class.

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2015-07-16 14:43
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.