Directory icons

time to read 3 min | 479 words

Since people got into RavenDb’s data directory and started messing around with things, I decided that I might as well try to stop them. Now, I can’t really stop anyone, but I can make it clear that the Data directory is off limit.

I decided to do it by giving the RavenDB directory its own icon. That led me toward a journey to understand exactly how the desktop.ini works. Eventually, I got this:

public class CreateFolderIcon : IStartupTask
{
    public void Execute(DocumentDatabase database)
    {
        var dataDirectory = Path.GetFullPath(database.Configuration.DataDirectory);
            
        var desktopIni = Path.Combine(dataDirectory, "desktop.ini");
        var icon = Path.Combine(dataDirectory, "raven-data.ico");

        if (File.Exists(desktopIni) && File.Exists(icon))
            return;

        using (var iconFile = typeof(CreateFolderIcon).Assembly.GetManifestResourceStream("Raven.Database.Server.WebUI.raven-data.ico"))
        {
            File.WriteAllBytes(icon, iconFile.ReadData());
        }

        File.WriteAllText(desktopIni, string.Format(@"
[.ShellClassInfo]
IconResource={0},0
[ViewState]
Mode=
Vid=
FolderType=Generic
",
                                icon));


        File.SetAttributes(desktopIni, FileAttributes.Hidden | FileAttributes.System | FileAttributes.Archive);
        File.SetAttributes(dataDirectory, FileAttributes.ReadOnly);

    }
}

And now the RavenDB data directory looks like:

image 

A few things to note:

  • This isn’t exactly what I envisioned as the usage scenario for startup tasks.
  • You have to use set the attributes on the desktop.ini to hidden, system & archive for it to work.
  • You have to set the attributes on the directory to read only. The documentation says that you need to call PathMakeSystemFolder, but you can just use File.SetAttributes (remember, a directory is a file, when all is said and done).

I think that this is cool, a bit useless, but cool. A bit of polish for the way RavenDB behaves.