代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

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

  •  6
  • Ian Boyd  · 技术社区  · 14 年前

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

    让我们使用六个示例文件:

    • 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:\develope\readme.txt文件
    • %CSIDL_Program_Files%\Adobe\Reader\WhatsNew.txt

    • c:\文档和;设置\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\u MyPictures%\女儿的制胜球.jpg

    我的照片 已存储 在里面 My Documents :

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

    %CSIDL_Profile%\Documents
    %CSIDL_Profile%\Pictures
    

    注: %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
    

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


    我在想:

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

    另请参见

    2 回复  |  直到 14 年前
        1
  •  2
  •   dguaraglia    14 年前

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

        2
  •  2
  •   Ian Boyd    14 年前
    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
    

    推荐文章