Windows Special Folders

Windows uses an enumeration of special folder names to make it easier to find commonly used folders. Without this mechanism, we’d have to jump through a lot more hoops to determine this information since it is user dependent. I was trying to use a special folder as the root of a path for some common files shared by multiple programs that I am working on.

(Squirrel!) I wonder where all these paths point to on my machine? Time to bang out some code to see. I don’t want users to be able to easily screw up my files so maybe I should pick a hidden folder to add some (little) protection.

Special Folder NameValue on 64-bit machineAttributes
AdminToolsC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative ToolsRO
ApplicationDataC:\Users\{username}\AppData\Roaming
CDBurning
CommonAdminToolsC:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative ToolsRO
CommonApplicationDataC:\ProgramDataH
CommonDesktopDirectoryC:\Users\Public\DesktopH, RO
CommonDocumentsC:\Users\Public\DocumentsRO
CommonMusicC:\Users\Public\MusicRO
CommonOemLinks
CommonPicturesC:\Users\Public\PicturesRO
CommonProgramFilesC:\Program Files (x86)\Common Files
CommonProgramFilesX86C:\Program Files (x86)\Common Files
CommonProgramsC:\ProgramData\Microsoft\Windows\Start Menu\ProgramsRO
CommonStartMenuC:\ProgramData\Microsoft\Windows\Start MenuRO
CommonStartupC:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartupRO
CommonTemplatesC:\ProgramData\Microsoft\Windows\Templates
CommonVideosC:\Users\Public\VideosRO
CookiesC:\Users\{username}\AppData\Local\Microsoft\Windows\INetCookiesH, Sys
DesktopC:\Users\{username}\DesktopRO
DesktopDirectoryC:\Users\{username}\DesktopRO
FavoritesC:\Users\{username}\FavoritesRO
FontsC:\Windows\FontsRO, Sys
HistoryC:\Users\{username}\AppData\Local\Microsoft\Windows\HistorySys
InternetCacheC:\Users\{username}\AppData\Local\Microsoft\Windows\INetCacheH, Sys
LocalApplicationDataC:\Users\{username}\AppData\Local
LocalizedResources
MyComputer
MyDocumentsC:\Users\{username}\DocumentsRO
MyMusicC:\Users\{username}\MusicRO
MyPicturesC:\Users\{username}\PicturesRO
MyVideosC:\Users\{username}\VideosRO
NetworkShortcutsC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Network Shortcuts
PersonalC:\Users\{username}\DocumentsRO
PrinterShortcutsC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Printer Shortcuts
ProgramFilesC:\Program Files (x86)RO
ProgramFilesX86C:\Program Files (x86)RO
ProgramsC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Start Menu\ProgramsRO
RecentC:\Users\{username}\AppData\Roaming\Microsoft\Windows\RecentRO
ResourcesC:\Windows\resources
SendToC:\Users\{username}\AppData\Roaming\Microsoft\Windows\SendToRO
StartMenuC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Start MenuRO
StartupC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\StartupRO
SystemC:\Windows\system32
SystemX86C:\Windows\SysWOW64
TemplatesC:\Users\{username}\AppData\Roaming\Microsoft\Windows\Templates
UserProfileC:\Users\{username}
WindowsC:\Windows
  1. H – Directories marked with this attribute do not appear in an ordinary directory listing.
  2. RO – Applications cannot delete this folder, but applications can create and delete files from that directory.
  3. Sys – Directory that the operating system uses a part of or uses exclusively.

If you are curious, this is the application I used to determine my values.

using System;
using System.Collections.Generic;
using System.IO;

namespace SpecialFolder
{
    class Program
    {
        static void Main(string[] args)
        {
            IList<string> folders = new List<String>() {
                "AdminTools", "ApplicationData", "CDBurning", "CommonAdminTools", "CommonApplicationData",
                "CommonDesktopDirectory", "CommonDocuments", "CommonMusic", "CommonOemLinks", "CommonPictures",
                "CommonProgramFiles", "CommonProgramFilesX86", "CommonPrograms", "CommonStartMenu",
                "CommonStartup", "CommonTemplates", "CommonVideos", "Cookies", "Desktop", "DesktopDirectory",
                "Favorites", "Fonts", "History", "InternetCache", "LocalApplicationData", "LocalizedResources",
                "MyComputer", "MyDocuments", "MyMusic", "MyPictures", "MyVideos", "NetworkShortcuts", "Personal",
                "PrinterShortcuts", "ProgramFiles", "ProgramFilesX86", "Programs", "Recent", "Resources", "SendTo",
                "StartMenu", "Startup", "System", "SystemX86", "Templates", "UserProfile", "Windows"
             };

            // Coded to create a Markdown format table in console.
            Console.WriteLine("|Special Folder Name| Value on 64-bit machine| Attributes |");
            Console.WriteLine("|--|--|--|");
            foreach (string folder in folders)
            {
                Environment.SpecialFolder specFolder
                    = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), folder);
                
                string envFolder = Environment.GetFolderPath(specFolder);
                if (String.IsNullOrWhiteSpace(envFolder))
                {
                    Console.WriteLine($"| {folder} |  |  |");
                    continue;
                }

                string attr = 
                    (File.GetAttributes(envFolder) & FileAttributes.Hidden) > 0 ? "H" : "";

                if ((File.GetAttributes(envFolder) & FileAttributes.ReadOnly) > 0)
                {
                    if (attr == "")
                    {
                        attr = "RO";
                    }
                    else
                    {
                        attr += ", RO";
                    }
                }

                if ((File.GetAttributes(envFolder) & FileAttributes.System) > 0)
                {
                    if (attr == "")
                    {
                        attr = "Sys";
                    }
                    else
                    {
                        attr += ", Sys";
                    }
                }

                string s = $"| {folder} | {Environment.GetFolderPath(specFolder)} | {attr} |";
                // Replace "xxxxx" with your username to hide output. If you don't care, remove the following line.
                s = s.Replace("xxxxx", "\\{username}");
                Console.WriteLine(s);
            }
        }
    }
}