![]() |
Parsen von EnvironmentPath
Wie würdet ihr vorgehen um den EnvironmentPath zu parsen..?
bsp. IExplorer setzt seinen Arbeitspfad mit %HOMEDRIVE%%HOMEPATH%.. Den Path stelle ich dann so zur Verfügung. @%HOMEDRIVE%@%HOMEPATH% Danach parse ich es auf diese weise.
Delphi-Quellcode:
function TShortCut.ExpandEnvironment(EnvironmentPath: PWideChar): PWideChar;
var lpDest: array [0 .. 32768] of WideChar; begin result := ''; FillChar(lpDest, SizeOf(lpDest), 0); if ExpandEnvironmentStrings(PWideChar(EnvironmentPath), lpDest, 32767) <> 0 then result := lpDest; end;
Delphi-Quellcode:
Das scheint mir irgendwie zu unsicher..
var
SplitID: TSplitStrArray; sTmpWork: WideString; begin sWorkDir := GetExePath(Trim(ParseThis(sBF, ',', 3)), ExtractFilePath(sShellTo)); SplitID := Split(sWorkDir, '@'); if (Length(SplitID) > 1) then begin if (MidStr(SplitID[1], 0, 1) = '%') then begin sTmpWork := SplitID[1]; sWorkDir := ExpandEnvironment(PWideChar(sTmpWork)); if Length(SplitID) > 1 then begin sTmpWork := SplitID[2]; sWorkDir := sWorkDir + ExpandEnvironment(PWideChar(sTmpWork)) + '\'; end; end; end; end; Könnte ja theoretisch auch nur %HOMEDRIVE% bzw. 3 aneinanderhängende enthalten sein. Um was es mir geht, suche eine bessere\sichere Lösung den EnvironmentPath zu parsen. Vielleicht hat ja jemand eine bessere Lösung. Eventuell über eine schleife oder TStringListe? gruss |
AW: Parsen von EnvironmentPath
Ich nutze eine Unit von Delphidabbler für Environment Parsing.
Wenn Dich das Interessieren sollte, ![]() |
AW: Parsen von EnvironmentPath
Ich nutze überhaupt nicht die Environment-Variablen, sondern die API-Funktion SHGetSpecialFolderLocation.
Meine Funktion sieht so aus (irgendwo mal aus dem Internet gefischt und angepasst):
Delphi-Quellcode:
Eine Liste der CSIDL-Werte ist hier zu finden:
function GetSpecialPath(aCSIDL : Integer) : String;
var shellMalloc: IMalloc; ppidl: PItemIdList; begin ppidl := nil; try if SHGetMalloc(shellMalloc) = NOERROR then begin SHGetSpecialFolderLocation(Application.Handle, aCSIDL, ppidl); SetLength(Result, MAX_PATH); if not SHGetPathFromIDList(ppidl, PChar(Result)) then begin Result := ''; end else begin SetLength(Result, lStrLen(PChar(Result))); end; end; finally if ppidl <> nil then begin shellMalloc.free(ppidl); end; end; end; ![]() In deinem Fall müsste es wohl CSIDL_PROFILE sein. |
AW: Parsen von EnvironmentPath
Warum so kompliziert? Laut der Doku
![]() Zitat:
Delphi-Quellcode:
in einem übergeben.
'%HOMEDRIVE%%HOMEPATH%'
BTW: Wer mit PWideChar arbeitet sollte auch konsequenterweise mit ExpandEnvironmentStringsW arbeiten, sonst ist bei der nächsten Umstellung (wie bei ANSI auf Unicode) das Geschrei wieder riesengross. PS: So würde diese Funktion bei mir aussehen:
Delphi-Quellcode:
function ExpandEnvironment( const AInput: string ): string;
var lResult: Cardinal; begin lResult := Winapi.Windows.ExpandEnvironmentStrings( PChar(AInput), nil, 0 ); if lResult = 0 then RaiseLastOSError( ); SetLength( Result, lResult ); lResult := Winapi.Windows.ExpandEnvironmentStrings( PChar(AInput), PChar( Result ), lResult ); if lResult = 0 then RaiseLastOSError( ); SetLength( Result, lResult - 1 ); end; |
AW: Parsen von EnvironmentPath
Ein wenig gekürzt bei gleicher funktionsweise abgesehen vom Errorcheck
Delphi-Quellcode:
edit
function ExpandEnvironment(const AInput: string): string;
const MAXSIZE = 32768; begin SetLength(Result, MAXSIZE); SetLength(Result, ExpandEnvironmentStrings(PChar(AInput), @Result[1], Length(Result)) - 1); end; Wobei mir Jasoculs Vorschlag in diesen Zusammenhang auch besser gefällt. |
AW: Parsen von EnvironmentPath
Zitat:
Danke an alle werde es mal umsetzen.. Zitat:
Die übergabe des Arbeitspfad ist nun mal von MS festgelegt die da lautet %HOMEDRIVE%%HOMEPATH% und hat nichts mit einer CSIDL zu tun. Es geht nicht darum was ich gern möchte sondern was vorgegeben ist.
Code:
zu
"c:\program files (x86)\internet explorer\iexplore.exe, IExplorer, @PATH@UserIcon\48x48\IExplorer.png, @PATH@, , 1"
Code:
gruss
"c:\program files (x86)\internet explorer\iexplore.exe, IExplorer, @PATH@UserIcon\48x48\IExplorer.png, %HOMEDRIVE%%HOMEPATH%, , 1"
|
AW: Parsen von EnvironmentPath
Zitat:
Wenn man ExpandEnvironmentStrings('%HOMEDRIVE%%HOMEPATH%') aufruft, bekommt man doch schon direkt das richtige Ergebnis (bei Bedarf vielleicht noch einen Backslash anhängen). |
AW: Parsen von EnvironmentPath
Zitat:
|
AW: Parsen von EnvironmentPath
Zitat:
Ich habe "@" angehängt um '%HOMEDRIVE%%HOMEPATH%' besser parsen zu können. Bei split wären das 3 einträge die da wären 0 = "", 1 = "C:" 2 = User\Name. Ich habe vorher nicht gewusst das man die Environment komplett übergeben kann bei mir kam da Kauderwelsch zu Stande deshalb der Umweg über Split. Wenn ich über "%" gesplittet hätte wäre das noch umständlicher weil mir dann "%" in den Strings gefehlt hätte. Zitat:
gruss |
AW: Parsen von EnvironmentPath
So geht's jetzt!
Delphi-Quellcode:
function TShortCut.ExpandEnvironment(EnvironmentPath: PWideChar): PWideChar;
var lpDest: array [0 .. 32768] of WideChar; begin result := ''; FillChar(lpDest, SizeOf(lpDest), 0); if ExpandEnvironmentStringsW(PWideChar(EnvironmentPath), lpDest, 32767) <> 0 then result := lpDest; end;
Delphi-Quellcode:
Danke für die Hilfe
sTmpWork := GetExePath(Trim(ParseThis(sBF, ',', 3)), ExtractFilePath(sShellTo));
if sTmpWork > '' then begin SplitID := Split(sTmpWork, '\'); if LeftStr(SplitID[High(SplitID)], 1) = '%' then sWorkDir := ExpandEnvironment(PWideChar(SplitID[High(SplitID)] + '\')) else sWorkDir := sTmpWork; end else sWorkDir := sTmpWork; gruss |
AW: Parsen von EnvironmentPath
Nur so nebenbei erwähnt:
Also, wenn man bei
Delphi-Quellcode:
den Split auf dem
'%HOMEDRIVE%%HOMEPATH%'
Delphi-Quellcode:
ausgeführt hätte, dann würde man folgendes erhalten:
'%'
Code:
Die Variablen-Namen (natürlich ohne die umschließenden %-Zeichen) findet man also an den ungeraden Positionen wieder.
0: ''
1: 'HOMEDRIVE' 2: '' 3: 'HOMEPATH' Diese hätte man also auch leicht durchlaufen können und wieder zusammenbauen können. |
AW: Parsen von EnvironmentPath
Zitat:
Habe meine alte Version nicht gegengeprüft. Das ist dann natürlich falsch! Zitat:
Aber gut mir der neuen Version geht es jetzt ohne Probleme. Muss hier zwar auch parsen aber das ist so sicherer wie vorher. (High(Array)) Falls diese frage noch aufkommt was ist "@PATH@" @PATH@ ist immer der Arbeitspfad (WorkDir) in dem die Exe liegt wenn nichts anderes angegeben wurde. Ist also eine globale variable für alle Verknüpfungen. gruss und Danke nochmals |
AW: Parsen von EnvironmentPath
Mag sein, daß es hier nicht relevant ist, weil der Rückgabewert gleich weiterverarbeitet wird, aber zeigt der Result von ExpandEnvironment nicht auf eventuell ungültigen Stackspeicher? lpDest liegt doch als lokale Variable auf dem Stack und der wird beim Verlassen der Methode freigegeben. (Mal abgesehen davon, daß der Methodenaufruf mal eben so 64k vom Stack abzwackt.)
Delphi-Quellcode:
function TShortCut.ExpandEnvironment(EnvironmentPath: PWideChar): PWideChar;
var lpDest: array [0 .. 32768] of WideChar; begin result := ''; FillChar(lpDest, SizeOf(lpDest), 0); if ExpandEnvironmentStringsW(PWideChar(EnvironmentPath), lpDest, 32767) <> 0 then result := lpDest; end; |
AW: Parsen von EnvironmentPath
Zitat:
|
AW: Parsen von EnvironmentPath
Zitat:
Mal davon abgesehen das mein Array schon immens definiert ist. Könnte das Array dynamisch machen so wie von @Schokohase vorgeschlagen. gruss |
AW: Parsen von EnvironmentPath
Zitat:
Ich würde es mir da ganz einfach machen und statt dessen überall mit
Delphi-Quellcode:
arbeiten, wo es die Windows-API nicht ausdrücklich anders vorschreibt.
string
|
AW: Parsen von EnvironmentPath
Zitat:
Delphi-Quellcode:
gruss
function TShortCut.ExpandEnvironment(const EnvironmentPath: string): string;
var lpDest: array [0 .. 32768] of WideChar; begin result := ''; FillChar(lpDest, SizeOf(lpDest), 0); if ExpandEnvironmentStringsW(PWideChar(EnvironmentPath), lpDest, 32767) <> 0 then result := lpDest; end; |
AW: Parsen von EnvironmentPath
Nur so zur Info:
Bei
Delphi-Quellcode:
nimmt man
string
Delphi-Quellcode:
und den API Aufruf ohne A oder W am Ende.
PChar
|
AW: Parsen von EnvironmentPath
Zitat:
Wenn ich PChar in D2010 verwende wird PChar automatisch nach PWideChar gecastet. Also gebe ich direkt den richtigen Typ an ;) gruss |
AW: Parsen von EnvironmentPath
Delphi-Quellcode:
bei < D2009 ist
string
Delphi-Quellcode:
.
AnsiString
Delphi-Quellcode:
bei >= D2009 ist
string
Delphi-Quellcode:
.
UnicodeString
Delphi-Quellcode:
bei < D2009 ist
PChar
Delphi-Quellcode:
.
PAnsiChar
Delphi-Quellcode:
bei >= D2009 ist
PChar
Delphi-Quellcode:
.
PWideChar
Es wird also automatisch umgeschaltet, je nach Version (kann man im Source auch nachlesen). Nur wenn du immer Ansi/Unicode habe willst, aber dann ist
Delphi-Quellcode:
auf jeden Fall nicht korrekt
string
|
AW: Parsen von EnvironmentPath
Zitat:
Warum soll ich es umschalten lassen wenn ich den Typ bereits kenne dann übergeben ich den richtigen direkt. Nun mit dem string! Die Api erwartet nun mal PWideChar von daher muss ich auch hier konvertieren.. Uwe meinte das wäre korrekt so :) gruss |
AW: Parsen von EnvironmentPath
Zitat:
Delphi-Quellcode:
nicht die richtige Lösung. Da in deinem Profil D2010 steht, bin ich natürlich auch davon ausgegangen.
string
Wenn es denn auch in diesen alten Versionen immer
Delphi-Quellcode:
sein soll, dann muss die Speicherverwaltung dafür eben auch selbst programmiert werden. In D7 gibt es halt keinen Unicode fähigen string-Typ. Da muss man dann alles selbst von Hand machen.
WideChar
|
AW: Parsen von EnvironmentPath
Zitat:
Ab D2010 ist ein String ein mächtiges Werkzeug von daher ist das schon IO.. Unter D2010 den Quelltext zu kompilieren ist nicht sinnvoll da ich Generics verwende die gibt es auch erst ab dieser Version. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz