windowsspecial-folderscanonicalizationroamingroaming-profile

Windows: How to canonicalize a file to the special folder?


i want to to persist some filenames for the user (e.g. recent files).

Let's use six example files:

i'm now hard-coding path to special folders. If the user redirects their folders, roams to another computer, or upgrades their operating system, the paths will be broken:

i want to be a good developer, and convert these hard-coded absolute paths to relative paths from the appropriate special folders:

The difficulty comes with the fact that there can be multiple representations for the same file, e.g.:

Note also that in Windows XP My Pictures are stored in My Documents:

%CSIDL_Profile%\My Documents
%CSIDL_Profile%\My Documents\My Pictures

But on Vista/7 they are separate:

%CSIDL_Profile%\Documents
%CSIDL_Profile%\Pictures

Note: i realize the syntax %CSIDL_xxx%\filename.ext is not valid; that Windows will not expand those keywords like they are environment strings. i'm only using it as a way to ask this question. Internally i would obviously store the items some other way, perhaps as a CSIDL parent and the tail of the path, e.g.:

 CSIDL_Personal         \Budget.xls
 CSIDL_MyPictures       \Daughter's Winning Goal.jpg
 CSIDL_AppData          \uTorrent
 CSIDL_Common_AppData   \Consonto\SpellcheckDictionary.dat
 -1                     c:\Develop\readme.txt   (-1, since 0 is a valid csidl)
 CSIDL_Program_Files    \Adobe\Reader\WhatsNew.txt

The question becomes, how to use, as much as possible, paths relative to canonical special folders?


I'm thinking:

void CanonicalizeSpecialPath(String path, ref CSLID cslid, ref String relativePath)
{
   return "todo";
}

See also


Solution

  • I suppose you could find out how the CSIDL map to paths (using something like SHGetKnownFolderPath), build a reverse dictionary of them, then check whether the beginning of the path you want to store matches any of the keys in the dictionary and then remove the beginning and store the CSIDL that matched.

    Not overtly elegant, but it should get the work done.