none
FileSystemWatcher Problem on Vista, Win7, etc. RRS feed

  • Question

  • I have a few lines of code that are supposed to monitor when plotfiles (output files) are appended (typically once every 10-20 s).  The code looks like this...

                    PlotFileWatchers.Add(New System.IO.FileSystemWatcher)
                    PlotFileWatchers(iPFW).NotifyFilter = IO.NotifyFilters.LastWrite + IO.NotifyFilters.Size + IO.NotifyFilters.CreationTime
                    PlotFileWatchers(iPFW).Path = nfo.DirectoryName
                    PlotFileWatchers(iPFW).Filter = nfo.Name
                    AddHandler PlotFileWatchers(iPFW).Changed, AddressOf OnChanged
                    PlotFileWatchers(iPFW).EnableRaisingEvents = True

    And it works great on WinXP...but not so on Vista, Win 7, even Server 2008.

    On the newer operating systems, the OnChanged function is not getting called.  I noticed even in Windows Explorer, the file size of the plot files says 1kb.  That is, until I either right-click and select "properties" on my plot file, then OnChanged gets called and Explorer updates the file size, or the plotfile is closed, that is the other time Explorer updates file properties, and OnChanged gets called.

    So how do I make FileSystemWatcher work?  Or, is it the latest cool thing to now use timers again to check if the file was changed?

    Please keep in mind this is basically a commercial application, so I'm not looking for a hack.

    Thursday, February 11, 2010 4:42 PM

Answers

All replies

  • Depends on the file system type I guess. For example, the last write time is not fully updated until all handles that are used for writing are closed, and NTFS candelays updates to the last access time for a file by up to 1 hour after the last access, or not at all if HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate is enabled.

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    • Marked as answer by SamAgain Monday, February 22, 2010 9:32 AM
    Thursday, February 11, 2010 6:02 PM
  • So basically you're saying that FileSystemWatcher.Changed just plain doesn't work?
    Thursday, February 11, 2010 6:25 PM
  • It works, just not in the way layed out in your requirements. Reconsider your requirements e.g. give up the reliability requirement or add a requirement to install a file filter driver 

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    • Marked as answer by SamAgain Monday, February 22, 2010 9:32 AM
    Thursday, February 11, 2010 7:37 PM
  • If anyone else runs into this...or Microsoft decides to get rid of the "fine print" for this feature...here's a fix:


        Public PlotFileInfoWatchers As New List(Of System.IO.FileInfo)

        Private WithEvents FileSystemWatcherWorkaroundTimer As New System.Windows.Threading.DispatcherTimer

        Private Sub FileSystemWatcherWorkaroundTimer_Tick(ByVal Sender As Object, ByVal e As System.EventArgs) Handles FileSystemWatcherWorkaroundTimer.Tick
            FileSystemWatcherWorkaroundTimer.Stop()
            For Each item As System.IO.FileInfo In PlotFileInfoWatchers
                item.Refresh()
            Next
            FileSystemWatcherWorkaroundTimer.Start()
        End Sub



                    'Lazy file writer (Vista+)...breaks FileSystemWatcher, so do a work-around
                    If System.Environment.OSVersion.Version.Major >= 6 AndAlso Not FileSystemWatcherWorkaroundTimer.IsEnabled Then
                        FileSystemWatcherWorkaroundTimer.Interval = New System.TimeSpan(0, 0, 3) 'Default to 3 s
                        'TODO Make FileSystemWatcherWorkaroundTimer.Interval user option
                        FileSystemWatcherWorkaroundTimer.Start()
                    End If
                    PlotFileInfoWatchers.Add(New System.IO.FileInfo(nfo.FullName))

    Friday, February 12, 2010 12:33 AM