Search code examples
c#visual-studio-2010filesystemwatcher

Sorting a folder of Visual Studio solutions by last write time


I have a folder with a bunch of Visual Studio 2010 solution folders in it.

In Windows Explorer, I'm sorting the folder in descending order of 'Date modified'.

If I modify a C# file deep in a solution folder somewhere, I'd like that solution folder to move to the top of the explorer listing. I.e. I'd like to have that folder be considered "modified".

Is there an extension to Visual Studio that enables this behavior? Or is there a more straightforward way to sort solutions such that the most recently modified ones appear first in Windows Explorer?

I threw together this C# program which uses FileSystemWatcher to monitor a folder for changes to *.cs files and touches it's corresponding VS solution folder. However, the call Directory.SetLastWriteTime(path, DateTime.Now) results in an exeption; it appears that when VS has a solution open, that directory is locked such that the SetLastWriteTime cannot update the time.

using System;
using System.IO;

namespace MyDocumentsWatcher
{
    class Program
    {
        static void Main(string[] args)
        {
            var watcher =
                new FileSystemWatcher()
                {
                    Path = "C:/Users/dharmatech/Documents",
                    Filter = "*.cs",
                    NotifyFilter = 
                        NotifyFilters.LastWrite |
                        NotifyFilters.FileName |
                        NotifyFilters.DirectoryName,
                    IncludeSubdirectories = true,
                    EnableRaisingEvents = true
                };

            watcher.Changed += (s, e) =>
                {
                    Console.WriteLine("{0} {1}", e.ChangeType, e.Name);

                    var path = e.FullPath;

                    while (true)
                    {
                        Console.WriteLine(path);
                        if (Path.GetDirectoryName(path) == @"C:\Users\dharmatech\Documents")
                        {
                            Directory.SetLastWriteTime(path, DateTime.Now);
                            break;
                        }
                        else
                            path = Path.GetDirectoryName(path);
                        System.Threading.Thread.Sleep(1000);
                    }
                };

            Console.ReadLine();
        }
    }
}

Any suggestions for how to achieve this are welcome!


Solution

  • My solution was to use the above program but with a minor tweak. Instead of trying update the LastWriteTime of the VS solution folder, I create and then delete a temporary file in that folder; that has the effect of updating the LastWriteTime. Here's that version of the program:

    using System;
    using System.IO;
    
    namespace MyDocumentsWatcher
    {
        class Program
        {
            static void Main(string[] args)
            {
                var random = new Random();
    
                var watcher =
                    new FileSystemWatcher()
                    {
                        Path = @"C:\Users\dharmatech\Documents",
                        Filter = "*.cs",
                        NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName,
                        IncludeSubdirectories = true,
                        EnableRaisingEvents = true
                    };
    
                watcher.Changed += (s, e) =>
                    {
                        Console.WriteLine("{0} {1}", e.ChangeType, e.Name);
    
                        var path = e.FullPath;
    
                        while (true)
                        {
                            if (Path.GetDirectoryName(path) == @"C:\Users\dharmatech\Documents")
                            {
                                var tmp = Path.Combine(path, random.Next().ToString());
                                using (File.Create(tmp)) { }
                                File.Delete(tmp);
                                break;
                            }
                            else
                                path = Path.GetDirectoryName(path);
                        }
                    };
    
                Console.ReadLine();
            }
        }
    }