NotifyFilter of FileSystemWatcher not working

2020-07-26 06:06发布

I have a windows service (and verified the code by creating a similar WinForms application) where the NotifyFilter doesn't work. As soon as I remove that line of code, the service works fine and I can see the event-handler fire in the WinForms application.

All I'm doing is dropping a text file into the input directory for the FileSystemWatcher to kick off the watcher_FileChanged delegate. When I have the _watcher.NotifyFilter = NotifyFilters.CreationTime; in there, it doesn't work. When I pull it out, it works fine.

Can anyone tell me if I'm doing something wrong with this filter?

Here is the FSW code for the OnStart event.

protected override void OnStart(string[] args)
{
    _watcher = new FileSystemWatcher(@"C:\Projects\Data\Test1");

    _watcher.Created += new FileSystemEventHandler(watcher_FileChanged);
    _watcher.NotifyFilter = NotifyFilters.CreationTime;
    _watcher.IncludeSubdirectories = false;
    _watcher.EnableRaisingEvents = true;
    _watcher.Error += new ErrorEventHandler(OnError);    
}

private void watcher_FileChanged(object sender, FileSystemEventArgs e)
{
    // Folder with new files - one or more files
    string folder = @"C:\Projects\Data\Test1";
    System.Console.WriteLine(@"C:\Projects\Data\Test1");
    //Console.ReadKey(true); 

    // Folder to delete old files - one or more files
    string output = @"C:\Temp\Test1\";
    System.Console.WriteLine(@"C:\Temp\Test1\");
    //Console.ReadKey(true);

    // Create name to call new zip file by date
    string outputFilename = Path.Combine(output, string.Format("Archive{0}.zip", DateTime.Now.ToString("MMddyyyy")));
    System.Console.WriteLine(outputFilename);
    //Console.ReadKey(true);

    // Save new files into a zip file
    using (ZipFile zip = new ZipFile())
    {
        // Add all files in directory
        foreach (var file in Directory.GetFiles(folder))
        {
            zip.AddFile(file);
        }

        // Save to output filename
        zip.Save(outputFilename);
    }

    DirectoryInfo source = new DirectoryInfo(output);
    // Get info of each file into the output directory to see whether or not to delete
    foreach (FileInfo fi in source.GetFiles())
    {
        if (fi.CreationTime < DateTime.Now.AddDays(-1))
            fi.Delete();
    }
}

2条回答
Luminary・发光体
2楼-- · 2020-07-26 06:24

I've been having trouble with this behavior too. If you step through the code (and if you look at MSDN documenation, you'll find that NotifyFilter starts off with a default value of:

NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite

So when you say .NotifyFilter = NotifyFilters.CreationTime, you're wiping out those other values, which explains the difference in behavior. I'm not sure why NotifyFilters.CreationTime is not catching the new file... seems like it should, shouldn't it!

You can probably just use the default value for NotifyFilter if it's working for you. If you want to add NotifyFilters.CreationTime, I'd recommend doing something like this to add the new value and not replace the existing ones:

_watcher.NotifyFilter = _watcher.NotifyFilter | NotifyFilters.CreationTime;
查看更多
疯言疯语
3楼-- · 2020-07-26 06:31

I know this is an old post but File Creation time is not always reliable. I came across a problem where a Log file was being moved to an archive folder and a new file of the same name was created in it's place however the file creation date did not change, in fact the meta data was retained from the previous file (the one that was moved to the archive) .

Windows has this cache on certain attributes of a file, file creation date is included. You can read the article on here: https://support.microsoft.com/en-us/kb/172190.

查看更多
登录 后发表回答