37

I have some code that uses FileSystemWatcher to monitor file changes outside of my application.

On Windows 7, using .NET 4, the below code would detect when a file had been edited and saved in an application like Notepad, while my app was running. However, this logic isn't working using .NET 4 on Windows 8. Specifically, the FileSystemWatcher's Changed event never fires.

public static void Main(string[] args)
{
    const string FilePath = @"C:\users\craig\desktop\notes.txt";

    if (File.Exists(FilePath))
    {
        Console.WriteLine("Test file exists.");
    }

    var fsw = new FileSystemWatcher();
    fsw.NotifyFilter = NotifyFilters.Attributes;
    fsw.Path = Path.GetDirectoryName(FilePath);
    fsw.Filter = Path.GetFileName(FilePath);

    fsw.Changed += OnFileChanged;
    fsw.EnableRaisingEvents = true;

    // Block exiting.
    Console.ReadLine();
}

private static void OnFileChanged(object sender, FileSystemEventArgs e)
{
    if (File.Exists(e.FullPath))
    {
        Console.WriteLine("File change reported!");
    }
}

I understand that I can alter the NotifyFilter to also include NotifyFilters.LastWrite, which can solve my problem. However, I want to understand why this code worked on Windows 7 but now fails to fire the Changed event on Windows 8. I'm also curious to know if there's a way to restore my Windows 7 FileSystemWatcher behavior when running in Windows 8 (without changing the NotifyFilter).

Craig
  • 1,890
  • 1
  • 26
  • 44
  • 6
    Have you been following Microsofts Online Support Suggestions posted on this web site I assume that you are that same Craig..http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/dbe6850c-2aa1-4813-8664-2086c0a3588b – MethodMan Nov 30 '12 at 00:41
  • Pure the documentation located here: http://msdn.microsoft.com/en-us/library/system.io.notifyfilters(v=vs.110).aspx it indicates it should work in Windows 8. Does the file in question even have an attributes? This appears to be a bug. For the time being you will have to use a workaround until its fixed. – Security Hound Nov 30 '12 at 00:42
  • 1
    there are a lot of things that should work Per "THERE DOCUMENTATION" but there are bugs even in .NET 4.0 that's broken working things that were in 3.5 and 2.0 – MethodMan Nov 30 '12 at 00:43
  • @DJKRAZE - I posted that commented as you posted your commented and linked to a thread which indicated an actual bug report was filed. They have only been looking at the bug report since 11/25/2012 its going to take awhile. – Security Hound Nov 30 '12 at 00:44
  • 2
    @DJKRAZE Yes, I am the same Craig. I posted here since the MSDN forum admin simply added my issue to Connect. While that's nice, Ramhound is correct that I won't be hearing back from MS for quite awhile. Further, I was hoping someone on StackOverflow could answer my actual question, which is **why** there's different behavior on Windows 8, not necessarily how to fix it. – Craig Nov 30 '12 at 17:22
  • I have found some bugs in the 4.0 release of .NET and I am assuming that this is another serious bug in regards to the Windows 8 OS.. – MethodMan Nov 30 '12 at 17:31
  • What other serious bugs have you found in .NET 4.0 on Windows 8? – Craig Nov 30 '12 at 18:12
  • This is odd. I could repro in .Net 4.5 on Win8. When I retargetted to 4.0 and rebuilt, the problem was gone. Now, when I retarget 4.5, the problem is still gone.. – Robert Jeppesen Dec 04 '12 at 11:20
  • @RobertJeppesen Did you make any other changes besides the retarget? – Craig Dec 04 '12 at 19:55
  • No, none at all. Changed target to 4.0, started working. Change back to 4.5, continued working. – Robert Jeppesen Dec 04 '12 at 20:32
  • @RobertJeppesen What program did you use to edit the file? – Craig Dec 07 '12 at 06:09
  • Your code was looking for changes to attributes, so I changed the read-only bit. (Right-click, properties etc) – Robert Jeppesen Dec 07 '12 at 07:27
  • Looks like there is an issue here, but to be sure, don't rely on `ReadLine` to block within managed code. Either include other `NotifyFilters` to ensure any events fire, or loop with `While (!Console.KeyAvailable) {Sleep(55); DoEvents; } `. (Untested C# code from a VB.NET programmer!) – Mark Hurd Dec 09 '12 at 14:30
  • I'm not sure why you expect it to fire, unless the file attributes are being changed, but you describe only editing a text file. If the file starts with the archive bit set (for example) simply editing it won't change any of the attributes. What happens when you use Explorer to actually change one of the file attributes? Perhaps the fact that it used to fire was a bug previous to .Net 4.5 and that bug has now been fixed, and your code behaves differently because you were relying on a bug. – Andy Dec 27 '12 at 18:37

5 Answers5

1

Check the archive bit on the file before/after you edit it. Your code is only searching for Attributes changes, so my guess is that Windows 7 is updating the Archive bit on the file, and windows 8 is not.

1

There are too many comments everywhere, I will just add an answer to verify that you are aware of the following issues:

Apparently the problem is that the event is raised on a background thread, and you need to marshal the call back to the UI thread.

I have experienced a lot of trouble with the FileSystemWatcher class, and decided not to use it as you can see me describe here: https://stackoverflow.com/a/22768610/129130 . It is possible, however, that the problems I experienced were due to thread synchronization issues and / or hardware issues.

Community
  • 1
  • 1
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
0

FileSystemWatcher is notoriously unreliable. Try subscribing to all the events and see if the others fire. One thing that you could try is to use a timer to examine the file for changes at regular intervals, say once every two seconds, instead of using FileSystemWatcher.

Alexandru Dicu
  • 1,151
  • 1
  • 16
  • 24
  • 3
    Although I've read about other people's troubles with FileSystemWatcher, we've had it working perfectly until Windows 8. Also, as I pointed out in my question, we already have a workaround by altering the NotifyFilter to include LastWrite. The question remains what changed on Windows 8 that's causing this code to no longer function. – Craig Dec 12 '12 at 22:39
0

I had the same problem. This class seems to work on my windows 8 computer:

https://stackoverflow.com/a/23743268/637142

Reason why I use that class is because it behaves the same on windows 7 and windows 8.

Community
  • 1
  • 1
Tono Nam
  • 34,064
  • 78
  • 298
  • 470
-1

I don't know why but I find that under Windows 8.1

NotifyFilters.LastWrite (Changed event) of class FileSystemWatcher will fire

  • if I monitor directory inside my desktop(C:\Users\[user]\Desktop).

the event will not fire

  • if I monitor program files directory (C:\Program Files (x86))

May be related to permission but I don't know how to config it, both condition are run under administrator

HyperDream
  • 1
  • 1
  • 2