Question

je veux persister certains noms de fichiers pour l'utilisateur (par exemple des fichiers récents).

Utilisons six fichiers par exemple:

  • 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

Je suis maintenant coder en dur chemin vers des dossiers spéciaux. Si l'utilisateur est redirigée leurs dossiers, se déplace vers un autre ordinateur, ou met à niveau leur système d'exploitation, les chemins seront brisés:

Je veux être un bon développeur, et les convertir codés en dur absolu chemins relatifs chemins dans les dossiers appropriés spéciaux :

  • %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

La difficulté vient du fait qu'il peut y avoir plusieurs représentations pour le même fichier, par exemple:.

  • 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

Notez également que dans Windows XP Mes images sont stockés My Documents:

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

Mais Vista / 7, ils sont séparés:

%CSIDL_Profile%\Documents
%CSIDL_Profile%\Pictures
  

Remarque: je me rends compte de la syntaxe   %CSIDL_xxx%\filename.ext n'est pas valide; cette   Windows ne se développe pas ces mots-clés   comme ils sont des chaînes d'environnement. je suis seulement   l'utiliser comme un moyen de demander ce   question. En interne i serait évidemment   stocker les éléments d'une autre façon, peut-être comme CSIDL parent   et la queue de la voie, par exemple:.

 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

La question est, comment utiliser, autant que possible, des chemins relatifs à des dossiers spéciaux canoniques?


Je pense:

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

Voir aussi

Était-ce utile?

La solution

Je suppose que vous pouvez savoir comment la carte CSIDL aux chemins (en utilisant quelque chose comme SHGetKnownFolderPath ), construire un dictionnaire inverse d'entre eux, puis vérifier si le début du chemin que vous voulez mémoriser correspond à l'une des clés dans le dictionnaire, puis retirez le début et stocker les CSIDL qui correspondent.

Pas ouvertement élégant, mais il doit faire le travail.

Autres conseils

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;

Et puis il y a une fonction qui « agrandit » les mots-clés de l'environnement spécial:

function ExpandSpecialPath(const path: string): string;
begin
   ...
end;

qui se dilate:

%CSIDL_PERSONAL%\4th quarter.xls

dans

\\RoamingProfileServ\Users\ian\My Documents\4th quarter.xls

Il le fait en recherchant% xx% au début de la chaîne, et l'étendre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top