views:

162

answers:

2

Is there a way to determine with the FSW if a file or a directory has been deleted?

A: 

You could interrogate the FileSystemEventArgs.FullPath property to tell if it is a directory or a file.

if (Path.GetFileName(e.FullPath) == String.Empty) 
{
    //it's a directory.
}

To check if it is a file or directory.

Yuriy Faktorovich
It was deleted, so these calls would fail, no?
Steven Sudit
@Steven Sudit: You'd have to check the FileSystemEventArgs.ChangeType property first then.
Yuriy Faktorovich
`File.GetAttributes` throws a `FileNotFoundException` for a deleted file.
Phil
@Yuriy: That's not going to help any. http://msdn.microsoft.com/en-us/library/t6xf43e0.aspx
Steven Sudit
@Steven Sudit: modified.
Yuriy Faktorovich
@Yuriy: I don't think this works. The `Path.GetFileName` has no crystal ball: it just manipulated text.
Steven Sudit
@Steven Sudit: Can you think of a case where it would not work, the documentation is specifically *If the last character of path is a directory or volume separator character, this method returns String.Empty*. Especially since FullPath *Gets the fully qualifed path of the affected file or directory*.
Yuriy Faktorovich
This expression doesn't evaluate to true for either a folder or a file.
Phil
@Phil: How did you test it? It works for me.
Yuriy Faktorovich
@Yuriy: You're making the false assumption that deleting a folder named "C:\abc\def" will fill `e.FullPath` with "C:\abc\def\". This is *not* the case.
Steven Sudit
@Steven Sudit: Why not? "C:\abc\def" would not be the fully qualified path, and FullPath returns a fully qualified one.
Yuriy Faktorovich
@Yuriy: As I've been saying, this turns out not to be the case. Rather than trust your interpretation of the documentation or my memory, I just tested it. I set a FSW on "C:\abc" and created a "def" subdirectory. I found that `e.FullPath` contained "C:\abc\def". Note the lack of any trailing backslash.
Steven Sudit
Do me a favor: please don't delete this answer. I think it's very educational.
Steven Sudit
@Steven Sudit Will do, I'd like to test this as well.
Yuriy Faktorovich
@Yuriy: Yes, please do. We could all benefit from a bit less reliance on authority and a bit more reliance on experimentation.
Steven Sudit
@yuriy, I created a FSW pointed at a folder copied your code into the delete handler and then created and deleted folders and text files. The handler was fired, but the expression evaluated to false for both files and folders.
Phil
@Phil: That is really strange, could you pastebin the code?
Yuriy Faktorovich
@yuriy: Do what?
Phil
@Phil: Use http://pastebin.com/ to show me your code.
Yuriy Faktorovich
+1  A: 

Here's a simplified and corrected version of fletcher's solution:

namespace Watcher
{
    class Program
    {
        private const string Directory = @"C:\Temp";
        private static FileSystemWatcher _fileWatcher;
        private static FileSystemWatcher _dirWatcher;

        static void Main(string[] args)
        {
             _fileWatcher = new FileSystemWatcher(Directory);
             _fileWatcher.IncludeSubdirectories = true;
             _fileWatcher.NotifyFilter = NotifyFilters.FileName;
             _fileWatcher.EnableRaisingEvents = true;
             _fileWatcher.Deleted += WatcherActivity;

            _dirWatcher = new FileSystemWatcher(Directory);
            _dirWatcher.IncludeSubdirectories = true;
            _dirWatcher.NotifyFilter = NotifyFilters.DirectoryName;
            _dirWatcher.EnableRaisingEvents = true;
            _dirWatcher.Deleted += WatcherActivity;

            Console.ReadLine();
        }

        static void WatcherActivity(object sender, FileSystemEventArgs e)
        {
            if(sender == _dirWatcher)
            {
                Console.WriteLine("Directory:{0}",e.FullPath);
            }
            else
            {
                Console.WriteLine("File:{0}",e.FullPath);
            }
        }
    }
}
Steven Sudit
+1. Your solution is far simpler
fletcher
I got the bugs out of it, but you did come up with the idea before I did.
Steven Sudit