Windows: eine Datei auf den speziellen Ordner normalisieren?
-
02-10-2019 - |
Frage
Ich mag einige Dateinamen für den Benutzer bestehen bleiben (z jüngste Dateien).
Lassen Sie uns die Verwendung sechs Beispieldateien:
-
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
Ich bin jetzt hart codierte Pfad zu speziellen Ordnern. Wenn der Benutzer ihre Ordner umleitet, durchstreift auf einen anderen Computer oder ein Upgrade ihres Betriebssystems, werden die Pfade gebrochen:
ich will ein guter Entwickler sein, und wandeln diese hartcodierte absolute Pfade zu relativ Pfade aus dem entsprechenden spezielle Ordner :
-
%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
Die Schwierigkeit kommt mit der Tatsache, dass es mehrere Darstellungen für die gleiche Datei sein kann, z.
-
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
Beachten Sie auch, dass in Windows XP Meine Bilder gespeichert sind My Documents
:
%CSIDL_Profile%\My Documents
%CSIDL_Profile%\My Documents\My Pictures
Aber auf Vista / 7 sie sind getrennt:
%CSIDL_Profile%\Documents
%CSIDL_Profile%\Pictures
Hinweis: wird mir klar, die Syntax
%CSIDL_xxx%\filename.ext
ist nicht gültig; Das Windows wird nicht erweitert diese Keywords wie sie sind Umwelt-Strings. Ich bin nur indem es als eine Möglichkeit, dies zu fragen Frage. Intern würde ich offensichtlich Speichern Sie die Artikel, auf eine andere Weise, vielleicht alsCSIDL
Eltern und der Schwanz des Weges, z.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
Die Frage ist, wie Sie, so viel wie möglich, Pfade in Bezug auf kanonischen spezielle Ordner?
Ich denke:
void CanonicalizeSpecialPath(String path, ref CSLID cslid, ref String relativePath)
{
return "todo";
}
Siehe auch
- MSDN: CSIDL Enumeration
- Neue alte Sache: Beware Benutzerprofile von Roaming
- Neue alte Sache: Passen Sie von umgeleiteten Ordnern, auch
- MSDN: PathCanonicalize Funktion
Lösung
Ich nehme an, Sie könnten herausfinden, wie die CSIDL Karte Pfade (mit so etwas wie SHGetKnownFolderPath ), ein Reverse-Wörterbuch von ihnen bauen, dann prüfen, ob der Beginn des Weges Sie speichern möchten stimmt mit einer der Schlüssel im Wörterbuch und dann den Anfang und bewahren Sie die CSIDL dass abgestimmt.
Nicht offen elegant, aber es sollte die Arbeit getan.
Andere Tipps
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;
Und dann gibt es eine Funktion, die „erweitert“ die besondere Umgebung keywords:
function ExpandSpecialPath(const path: string): string;
begin
...
end;
, die erweitert:
%CSIDL_PERSONAL%\4th quarter.xls
in
\\RoamingProfileServ\Users\ian\My Documents\4th quarter.xls
Es tut es, indem Sie für% xx% zu Beginn des Strings, und erweitert es.