Windows:如何将文件化为特殊文件夹?
-
02-10-2019 - |
题
我想持续一些用户的文件名(例如最近的文件)。
让我们使用六个示例文件:
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
但是在Vista/7上,它们是独立的:
%CSIDL_Profile%\Documents
%CSIDL_Profile%\Pictures
笔记: 我意识到语法
%CSIDL_xxx%\filename.ext
无效;该窗口不会像环境字符串那样扩展这些关键字。我只是将其用作提出这个问题的一种方式。在内部,我显然会以其他方式存储这些物品,也许是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
问题变成了相对于规范特殊文件夹的方法,如何使用路径?
我在想:
void CanonicalizeSpecialPath(String path, ref CSLID cslid, ref String relativePath)
{
return "todo";
}
也可以看看
- MSDN: CSIDL枚举
- 新老东西: 当心漫游用户配置文件
- 新老东西: 当心重定向文件夹
- MSDN: 路径化功能
解决方案
我想您可以找出CSIDL如何映射到路径(使用类似的东西 Shgetnown Folderpath),构建它们的反向字典,然后检查您要存储的路径的开头是否匹配字典中的任何键,然后删除开始并存储匹配的csidl。
不是公开优雅,但应该完成工作。
其他提示
function CanonicalizeSpecialPath(const path: string): string;
var
s: string;
BestPrefix: string;
BestCSIDL: Integer;
i: Integer;
begin
BestPrefix := ''; //Start with no csidl being the one
BestCSIDL := 0;
//Iterate over the csidls i know about today for Windows XP.
for i := Low(csidls) to High(csidls) do
begin
//Get the path of this csidl. If the OS doesn't understand it, it returns blank
s := GetSpecialFolderPath(0, i, False);
if s = '' then
Continue;
//Don't do a string search unless this candidate is larger than what we have
if (BestPrefix='') or (Length(s) > Length(BestPrefix)) then
begin
//The special path must be at the start of our string
if Pos(s, Path) = 1 then //1=start
begin
//This is the best csidl we have so far
BestPrefix := s;
BestCSIDL := i;
end;
end;
end;
//If we found nothing useful, then return the original string
if BestPrefix = '' then
begin
Result := Path;
Exit;
end;
{
Return the canonicalized path as pseudo-environment string, e.g.:
%CSIDL_PERSONAL%\4th quarter.xls
}
Result := '%'+CsidlToStr(BestCSIDL)+'%'+Copy(Path, Length(BestPrefix)+1, MaxInt);
end;
然后有一个“扩展”特殊环境关键字的函数:
function ExpandSpecialPath(const path: string): string;
begin
...
end;
扩展:
%CSIDL_PERSONAL%\4th quarter.xls
进入
\\RoamingProfileServ\Users\ian\My Documents\4th quarter.xls
它通过在字符串开始时寻找%xx%并扩展它来做到这一点。
不隶属于 StackOverflow