Search code examples
c#.netms-wordfilesystemwatcher

FileSystemWatcher not firing Events from Office file changes


I'm trying to use a FileSystemWatcher to mirror two directories, but I've hit a hurdle with Office files. I don't seem to be able to get an event when a document/spreadsheet etc changes. This isn't to say that I'm not receiving any events however, as I understand the office apps frequently use temp files.

Here's an example of what I'm seeing, using the following code:

// Create the new watcher and hook up events
FileSystemWatcher fsw = new FileSystemWatcher(source);
fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.LastAccess | NotifyFilters.CreationTime | NotifyFilters.Security;
fsw.IncludeSubdirectories = true;
fsw.InternalBufferSize = 64000;
fsw.Renamed += Fsw_Renamed;
fsw.Error += Fsw_Error;
fsw.Deleted += (o, e) => OnChange(pair, e);
fsw.Changed += (o, e) => OnChange(pair, e);
fsw.Created += (o, e) => OnChange(pair, e);
fsw.EnableRaisingEvents = true;

The events that I see are as follows (using breakpoints in onChange, Fsw_Error and Fsw_Renamed):

I create the word document

  1. Created New Microsoft Word Document.docx
  2. Changed New Microsoft Word Document.docx

I open the word document

  1. Created ~$w Microsoft Word Document.docx
  2. Changed ~$w Microsoft Word Document.docx
  3. Changed ~$w Microsoft Word Document.docx

I edit and then save the word document

  1. Created ~WRD0000.tmp

I make more edits and then saves the word document

No events...

I really don't quite understand how this is working. The original docx file is being updated, but I'm not seeing any rename events or modifications. Is there something I'm missing here?


Solution

  • The documentation here indicates the Filter property needs to be set

    Even the example below the documentation seems to explicitly set the Filter property

    Quoted from there

    To watch for changes in all files, set the Filter property to an empty string ("") or use wildcards ("."). To watch a specific file, set the Filter property to the file name. For example, to watch for changes in the file MyDoc.txt, set the Filter property to "MyDoc.txt". You can also watch for changes in a certain type of file. For example, to watch for changes in text files, set the Filter property to "*.txt".

    In your case you could try setting it to *.docx

    Update

    From the comments below, its clear the above didnt work.

    I wrote a simple console program like so

    class Program
    {
        static void Main(string[] args)
        {
            var source = "D:\\temp\\folder";
    
            // Create the new watcher and hook up events
            var fsw = new FileSystemWatcher(source)
            {
                NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.LastAccess | NotifyFilters.CreationTime | NotifyFilters.Security,
                IncludeSubdirectories = true,
                InternalBufferSize = 64000
            };
    
            using (fsw)
            {
                fsw.Renamed += (o, e) => Console.WriteLine($"{e.OldFullPath} renamed to {e.FullPath}");
                fsw.Error += (o, e) => Console.WriteLine($"{e}");
                fsw.Deleted += (o, e) => Console.WriteLine($"{e.FullPath} deleted");
                fsw.Changed += (o, e) => Console.WriteLine($"{e.FullPath} changed");
                fsw.Created += (o, e) => Console.WriteLine($"{e.FullPath} created");
                fsw.EnableRaisingEvents = true;
    
                Console.WriteLine("Ready. Press 'Q' to exit");
                while (Console.ReadKey().KeyChar != 'Q')
                {
                }
            }
        }
    }
    

    which produces the following output

    at launch

    Ready. Press 'Q' to exit
    

    creating a new document

    D:\temp\folder\Doc1.docx created
    D:\temp\folder\Doc1.docx deleted
    D:\temp\folder\Doc1.docx created
    D:\temp\folder\~WRD0000.tmp created
    D:\temp\folder\~WRD0000.tmp changed
    D:\temp\folder\~WRD0000.tmp changed
    D:\temp\folder\~WRD0000.tmp changed
    D:\temp\folder\~WRD0000.tmp changed
    D:\temp\folder\~WRD0000.tmp changed
    D:\temp\folder\~WRD0000.tmp changed
    D:\temp\folder\Doc1.docx renamed to D:\temp\folder\~WRL0001.tmp
    D:\temp\folder\~WRD0000.tmp renamed to D:\temp\folder\Doc1.docx
    D:\temp\folder\~WRL0001.tmp changed
    D:\temp\folder\Doc1.docx changed
    D:\temp\folder\Doc1.docx changed
    D:\temp\folder\~WRL0001.tmp changed
    D:\temp\folder\~$Doc1.docx created
    D:\temp\folder\~$Doc1.docx changed
    D:\temp\folder\~WRL0001.tmp deleted
    

    editing the document

    D:\temp\folder\~WRD0002.tmp created
    D:\temp\folder\~WRD0002.tmp changed
    D:\temp\folder\~WRD0002.tmp changed
    D:\temp\folder\~WRD0002.tmp changed
    D:\temp\folder\~WRD0002.tmp changed
    D:\temp\folder\~WRD0002.tmp changed
    D:\temp\folder\~WRD0002.tmp changed
    D:\temp\folder\Doc1.docx renamed to D:\temp\folder\~WRL0003.tmp
    D:\temp\folder\~WRD0002.tmp renamed to D:\temp\folder\Doc1.docx
    D:\temp\folder\~WRL0003.tmp changed
    D:\temp\folder\Doc1.docx changed
    D:\temp\folder\Doc1.docx changed
    D:\temp\folder\~WRL0003.tmp changed
    D:\temp\folder\~WRL0003.tmp deleted
    

    more edits

    D:\temp\folder\~WRD0004.tmp created
    D:\temp\folder\~WRD0004.tmp changed
    D:\temp\folder\~WRD0004.tmp changed
    D:\temp\folder\~WRD0004.tmp changed
    D:\temp\folder\~WRD0004.tmp changed
    D:\temp\folder\~WRD0004.tmp changed
    D:\temp\folder\~WRD0004.tmp changed
    D:\temp\folder\Doc1.docx renamed to D:\temp\folder\~WRL0005.tmp
    D:\temp\folder\~WRD0004.tmp renamed to D:\temp\folder\Doc1.docx
    D:\temp\folder\~WRL0005.tmp changed
    D:\temp\folder\Doc1.docx changed
    D:\temp\folder\Doc1.docx changed
    D:\temp\folder\~WRL0005.tmp changed
    D:\temp\folder\~WRL0005.tmp deleted
    

    close word

    D:\temp\folder\~$Doc1.docx deleted
    

    delete from explorer

    D:\temp\folder\Doc1.docx deleted
    

    If you run this sample code and see similar (and expected) output like I did, you could modify your code to use this.