Windows:如何将文件规范化为特殊文件夹?

Ian*_*oyd 6 windows roaming special-folders roaming-profile canonicalization

我想为用户保留一些文件名(例如最近的文件).

我们使用六个示例文件:

  • c:\Documents & Settings\Ian\My Documents\Budget.xls
  • c:\Documents & Settings\Ian\My Documents\My Pictures\Daughter's Winning Goal.jpg
  • c:\Documents & Settings\Ian\Application Data\uTorrent
  • c:\Documents & Settings\All Users\Application Data\Consonto\SpellcheckDictionary.dat
  • c:\Develop\readme.txt
  • c:\Program Files\Adobe\Reader\WhatsNew.txt

我现在正在硬编码特殊文件夹的路径.如果用户重定向其文件夹,漫游到另一台计算机或升级其操作系统,则路径将被破坏:

我想成为一名优秀的开发人员,并将这些硬编码的绝对路径转换为相应的特殊文件夹中的相对路径:

  • %CSIDL_Personal%\Budget.xls
  • %CSIDL_MyPictures%\Daughter's Winning Goal.jpg
  • %CSIDL_AppData%\uTorrent
  • %CSIDL_Common_AppData%\Consonto\SpellcheckDictionary.dat
  • c:\Develop\readme.txt
  • %CSIDL_Program_Files%\Adobe\Reader\WhatsNew.txt

困难在于同一文件可以有多个表示,例如:

  • c:\Documents & Settings\Ian\My Documents\My Pictures\Daughter's Winning Goal.jpg
  • %CSIDL_Profile%\My Documents\My Pictures\Daughter's Winning Goal.jpg
  • %CSIDL_Personal%\My Pictures\Daughter's Winning Goal.jpg
  • %CSIDL_MyPictures%\Daughter's Winning Goal.jpg

另请注意,在Windows XP中,我的图片存储在 My Documents:

%CSIDL_Profile%\My Documents
%CSIDL_Profile%\My Documents\My Pictures
Run Code Online (Sandbox Code Playgroud)

但在Vista/7上它们是分开的:

%CSIDL_Profile%\Documents
%CSIDL_Profile%\Pictures
Run Code Online (Sandbox Code Playgroud)

注意:我意识到语法 %CSIDL_xxx%\filename.ext无效; Windows不会扩展这些关键字,就像它们是环境字符串一样.我只是用它来提问这个问题.在内部我显然会以其他方式存储项目,可能作为CSIDL 父项 和路径的尾部,例如:

 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
Run Code Online (Sandbox Code Playgroud)

问题是,如何尽可能多地使用相对于规范特殊文件夹的路径?


我在想:

void CanonicalizeSpecialPath(String path, ref CSLID cslid, ref String relativePath)
{
   return "todo";
}
Run Code Online (Sandbox Code Playgroud)

也可以看看

dgu*_*lia 2

我想您可以找出 CSIDL 如何映射到路径(使用类似SHGetKnownFolderPath之类的东西),构建它们的反向字典,然后检查要存储的路径的开头是否与字典中的任何键匹配,然后删除开始并存储匹配的 CSIDL。

不太优雅,但它应该可以完成工作。