Pregunta

quiero persistir algunos nombres de archivo para el usuario (por ejemplo, archivos recientes).

Vayamos de uso seis archivos de ejemplo:

  • 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

Ahora estoy ruta a carpetas especiales y difíciles de codificación. Si el usuario vuelve a dirigir sus carpetas, esté conectado a otra computadora, o actualiza su sistema operativo, los caminos se pueden dividir:

quiero ser un desarrollador bueno, y convertir éstos no modificable absoluta rutas de acceso a relativa Trazados de la adecuada carpetas especiales :

  • %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 dificultad viene con el hecho de que no puede haber múltiples representaciones para el mismo archivo, por ejemplo:.

  • 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

Tenga en cuenta también que en Windows XP Mis imágenes se almacenan My Documents:

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

Pero en Vista / 7 están separadas:

%CSIDL_Profile%\Documents
%CSIDL_Profile%\Pictures

Nota: i cuenta de la sintaxis %CSIDL_xxx%\filename.ext no es válido; ese Windows no se expandirá las palabras clave como son cadenas de entorno. Solo soy usarlo como una manera de hacer esta pregunta. Internamente me gustaría, obviamente, almacenar los elementos de alguna otra manera, tal vez como un CSIDL padres y la cola de la ruta, por ejemplo:.

 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 pregunta es, cómo utilizar, tanto como sea posible, caminos relativa a las carpetas especiales canónicos?


Estoy pensando en:

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

Ver también

¿Fue útil?

Solución

supongo que se podría averiguar cómo el mapa CSIDL de caminos (usando algo así como SHGetKnownFolderPath ), construir un diccionario inverso de ellos, a continuación, comprobar si el principio de la ruta que desea almacenar coincide con alguna de las teclas en el diccionario y luego retire el principio y almacenar el CSIDL que coincidía.

No abiertamente elegante, pero debe hacer el trabajo.

Otros consejos

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;

Y entonces hay una función que "se expande" las palabras clave de entorno especiales:

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

que se expande:

%CSIDL_PERSONAL%\4th quarter.xls

en

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

Lo hace mediante la búsqueda de% xx% al inicio de la cadena, y la ampliación de la misma.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top