Faisal Faisal - 6 months ago 95
Vb.net Question

Cannot monitor word docs using FileSystemWatcher

I have a folder that contains multiple word documents. I need to monitor this folder for any changes in these word documents. I am facing the following problems:


  1. FileSystemWatcher
    never reports the exact name of file being changed. For example for file abc.doc, it reports "~$abc.doc is changed" on first save.

  2. For all subsequent saves to that file,
    OnChanged
    event in the following code is not called. When I changed the filter to
    watcher.Filter = "*.*"
    , I found that for subsequent saves, it reports "~WRL0001.tmp is changed".



So the bottom line is that I never know the exact name of the file changed.

I am using the following code

public static void Main()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"C:\Users\Administrator\Documents\"; //"
watcher.NotifyFilter = NotifyFilters.Size;
watcher.Filter = "*.doc";
watcher.Changed += new FileSystemEventHandler(OnChanged);

watcher.EnableRaisingEvents = true;

Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}

Answer

File system watcher never reports the exact name of file being changed. For example for file abc.doc, it reports "~$abc.doc is changed" on first save.

The reason for this is that Word creates several temp files in the current directory where the original file is opened and the FileChanged event is fired when a new file is created also. In fact, FileSystemWatcher fires FileCreated followed by a FileChanged event. Since you don't subscribe to FileCreated you are only seeing the FileChanged notification.

For all subsequent saves to that file, OnChanged event in the following code is not called. When I changed the filter to watcher.Filter = ".", I found that for subsequent saves, it reports "~WRL0001.tmp is changed".

Same as above.

But I was curious about your problem and I did a little change to your program and modified it as follows (posting only relevant lines):

watcher.NotifyFilter =   NotifyFilters.Attributes;
watcher.Filter = "*.doc";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;

And then I saw the actual name of the file being changed printed on the console when the file was saved. When I looked at what attributes had changed in the original document from one save to the next one, I noticed that the revision number was being incremented by 1 (I know, revision number is not a file attribute from the OS point of view). I'm sure other attributes -for lack of a better word- got changed. It's up to you if you want to set the NotificationFilter to NotifyFilters.Attributes; to make this work but it is definitely odd that it wouldn't work by having NotificationFilter =NotifyFilters.Size | NotifyFilters.LastWrite; for example.

enter image description here