Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Die Funktion GetEnvironmentVariable ist mir bekannt.
Bevor ich jedoch gleiche eine Funktion bastle die einen Pfad mit Umgebungsvariablen (z. B. "%USERPROFILE%\SendTo") auflöst, wollte ich fragen ob es bereits etwas fertiges gibt. Und wenn wir schon dabei sind, vielleicht gibt es auch eine Funktion die automatisch aus normalen Pfaden einen Pfad mit Umgebungsvariablen erstellt. Wie gesagt, nur eine Frage. |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Delphi-Quellcode:
ExpandEnvironmentStrings('%USERPROFILE%\SendTo',Pchar(s),Length(s));
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Zitat:
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Vielen Dank. Irgendwie hatte ich da die richtige Vermutung.
Zitat:
Wie soll man die Funktion nun verstehen? Zuerst die Funktion auf gut Glück ausführen um zu gucken ob alles ok ist, wenn nicht, dann ein zweites Mal mit den richtigen Werten? |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Zitat:
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Ok, das mit dem "auf gut Glück" war etwas übertrieben formuliert, aber ist das tatsächlich so gedacht? Interessante Methode.
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Das gibt es in der Win32-API immer wieder mal.
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Aber das ist doch bei einigen API-Funktionen so, das man einen Buffer übergibt und z.B. ein Word? Der Buffer enthält dann soviel Inhalt wie reinpasste und die Word-Variable die Info, wie groß der Buffer hätte sein sollen.
Manchmal weiß man ja ungefähr wieviel zurückkommt, dann kann man dann direkt beim ersten mal einen großzügig bemessenen Buffer bereitstellen und dann diesen dann später nur bis zur benötigten/angegebenen Länge auslesen. |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Ja, aber wozu einen "zu großen" Puffer deklarieren, wenn man die tatsächlich benötigte Größe vorher ermitteln kann?
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Trotz dem eine interessante Methode.
Wie gesagt, mein Englisch ist verbesserungswürdig. Nun habe ich mich der PathUnExpandEnvStrings Funktion gewidmet. Kann man über eine Unit drauf zugreifen? Weiß das einer? |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Delphi-Quellcode:
unit Path_Utils;
// Thomas Wassermann (Bummi) interface uses Windows; Function ExpandEnvironmentStrings_D(Const s:String):String; Function PathUnExpandEnvStrings_D(Const s:String):String; {$IFDEF UNICODE} Function PathUnExpandEnvStrings(pszPath, pszBuf: PChar; cchBuf: UINT): BOOL; stdcall; {$ELSE} Function PathUnExpandEnvStrings(pszPath, pszBuf: PChar; cchBuf: UINT): BOOL; stdcall; {$ENDIF} implementation {$IFDEF UNICODE} Function PathUnExpandEnvStrings; External 'shlwapi.dll' Name 'PathUnExpandEnvStringsW'; {$ELSE} Function PathUnExpandEnvStrings; External 'shlwapi.dll' Name 'PathUnExpandEnvStringsA'; {$ENDIF} Function ExpandEnvironmentStrings_D(Const s:String):String; begin SetLength(Result,ExpandEnvironmentStrings(PChar(s),Pchar(Result),0)); ExpandEnvironmentStrings(Pchar(s),Pchar(Result),Length(Result)); end; Function PathUnExpandEnvStrings_D(Const s:String):String; var i:Integer; begin SetLength(Result,MAX_PATH); PathUnExpandEnvStrings(PChar(s),Pchar(Result),MAX_PATH); Result := PChar(Result); end; end. |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Danke. Hab gerade mit den Hausmitteln eine Alternative gebastelt, aber ich glaube deine Unit ist besser.
Delphi-Quellcode:
Ich glaube ich nehme deine Unit, die beinhaltet ja gleich beide Funktionen.
var
EnvStrings: array[0..6] of String = ('ALLUSERSPROFILE', 'APPDATA', 'TEMP', 'COMMONPROGRAMFILES', 'PROGRAMFILES', 'SYSTEMROOT', 'USERPROFILE'); function PathUnExpandEnvStrings2(Path: String): String; var i, p: Integer; s: String; begin Result := Path; for i := Low(EnvStrings) to High(EnvStrings) do begin p := Pos(UpperCase(GetEnvironmentVariable(EnvStrings[i])), UpperCase(Path)); if p > 0 then begin Delete(Result, p, Length(GetEnvironmentVariable(EnvStrings[i]))); Insert('%'+EnvStrings[i]+'%', Result, p); Exit; end; end; end; |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Die JCL macht das so (Unit JclSysInfo).
Auch keine schlechte Lösung; über den boolschen Resultwert erfährt man ob etwas expandiert wurde.
Delphi-Quellcode:
function ExpandEnvironmentVar(var Value: string): Boolean;
var R: Integer; Expanded: string; begin SetLength(Expanded, 1); R := ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), 0); SetLength(Expanded, R); Result := ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), R) <> 0; if Result then begin StrResetLength(Expanded); Value := Expanded; end; end; |
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Nur daß der von der JCL wohl auch nicht wirklich Ahnung hatte.
|
AW: Funktion zum auflösen von Pfaden mit Umgebungsvariablen?
Oder wieso findete man das
Delphi-Quellcode:
dort?
SetLength(Expanded, 1);
Nja, und dann soll laut MSDN die ANSI-Version einen Bug haben (auch wenn er wohl spätestens im Win7 schon nicht mehr vorhanden zu sein scheint), wonach dort der Buffer ein Byte größer sein muß. Variante 1 nach MSDN-Vorgaben und möglichst direkt in den Zielpuffer (Result-String). OK, abgesehn von dem Bugfix für's ANSI, aber FastMM wird die Speicherverwaltung optimieren und zu mindestens 99% nichts umkopieren.
Delphi-Quellcode:
Variante 1 ohne den Bugfix (für aktuellere Windowse):
function ExpandEnvironmentVars(var Value: string): Boolean;
var R: Integer; Expanded: string; begin R := ExpandEnvironmentStrings(PChar(Value), nil, 0); if R = 0 then Exit(False); {$IFDEF UNICODE} SetLength(Expanded, R - 1); Result := ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), R) = R; {$ELSE} SetLength(Expanded, R); Result := ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), R + 1) = R; SetLength(Expanded, R - 1); {$ENDIF} if Result then Value := Expanded; end;
Delphi-Quellcode:
Variante 2 inkl. Bugfix und mit Zwischenpuffer auf'm Stack.
function ExpandEnvironmentVars(var Value: string): Boolean;
var R: Integer; Expanded: string; begin R := ExpandEnvironmentStrings(PChar(Value), nil, 0); if R = 0 then Exit(False); SetLength(Expanded, R - 1); Result := ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), R) = R; if Result then Value := Expanded; end;
Delphi-Quellcode:
Da man die Umkehrfunktion sowieso nach Variante 2 bauen muß, könnte man Beides nach der gleichen Version deklarieren. (vorallem da es sich positiv auf den Bugfix auswirkt)
function ExpandEnvironmentVars(var Value: string): Boolean;
var Buffer: array[0..MAX_PATH] of Char; // maximal 32 KB R: Integer; begin R := ExpandEnvironmentStrings(PChar(Value), @Buffer, MAX_PATH {$IFDEF UNICODE}+ 1{$ENDIF}); Result := (R > 0) and (R < MAX_PATH); if Result then SetString(Value, Buffer, R - 1); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz