ExpandEnvironmentStrings Plattformübergreifend?
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
ExpandEnvironmentStrings Plattformübergreifend?
Hallo,
Ich suche ein"ExpandEnvironmentStrings" das Plattformüberfreifend funktioniert.
Ich möchte in einer INI-Datei Parameter von Pfadangaben haben, der auch Environment Variablen enthalten kann und das soll dann in einen absoluten Pfad gewandelt werden.
Kann mir jemand schreiben, welche Funktion ich verwenden kann um einen UTF8 String zu wandeln und welche Unit ich einbinden muss?
Vielen Dank, Gruß Markus.
Ich suche ein"ExpandEnvironmentStrings" das Plattformüberfreifend funktioniert.
Ich möchte in einer INI-Datei Parameter von Pfadangaben haben, der auch Environment Variablen enthalten kann und das soll dann in einen absoluten Pfad gewandelt werden.
Kann mir jemand schreiben, welche Funktion ich verwenden kann um einen UTF8 String zu wandeln und welche Unit ich einbinden muss?
Vielen Dank, Gruß Markus.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: ExpandEnvironmentStrings Plattformübergreifend?
MmVisual hat geschrieben:um einen UTF8 String zu wandeln
Das kommt darauf an, was du hast und wo du hin möchtest.
Such mal (bspw. in der Suche auf der Portal-Seite) nach Utf8ToSys, UTF8toAnsi, UTF8ToConsol bzw. umgekehrt. Bei Pfadangaben musst du auch wieder aufpassen, welche Zeichenkodierung dein System erwartet.
Zum ersetzen:
Mit GetEnvironmentVariableCount() erhältst du die Anzahl aller verfügbaren Variablen, die du mit GetEnvironmentString() bzw. GetEnvironmentStringUTF8() auslesen kannst. Da suchst du nach einem Gleichheitszeichen. Der erste Teil ist der Name; hinten steht der Wert (kann möglicherweise leer sein).
Wie die zu ersetzende Zeichenkette aussieht, musst du wissen; Unter Windows ist ein %VARNAME% üblich, unter Linux ein $VARNAME. Ein StringReplace() ersetzt dann die Zeichenkette.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
Ich habe eine INI-Datei mit z.B. den Parameter:
[Programm]
TempDir=C:\Temp
Damit ist es kein Problem.
Nun soll auch folgende Eingabe in der INI Datei möglich sein:
[Programm]
TempDir=%TEMP%\MeinTemp
Bzw. unter Linux:
[Programm]
TempDir=$HOME\MeinTemp
Ich lese mit TIniFile und ReadString diesen Wert ein in eine Variable vom Typ "String". Damit ist das ganze UTF8 Codiert.
Nun möchte ich eine Lazarus-Funktion aufrufen, die mir diese Environment-Variablen extrahiert und ich als String den absoluten Pfad stehen habe, als UTF8.
Wenn andere Funktionen eine andere Codierung benötigen, dann wandle ich das, damit habe ich keine Probleme.
So wie Du beschrieben hast, zu Fuß das machen, wäre zwar möglich, aber ich denke unter Linux ist das ersetzen etwas schwieriger, da man nicht genau weiß wann nun die Variable zu Ende ist, denn es gibt nur eine eindeutige Start-Kennung mit "$". Daher die Frage, gibt es eine fertige Funktion, die ich nur aufrufen brauche, so wie unter Windows?
Vielen Dank für die Infos.
Gruß Markus.
[Programm]
TempDir=C:\Temp
Damit ist es kein Problem.
Nun soll auch folgende Eingabe in der INI Datei möglich sein:
[Programm]
TempDir=%TEMP%\MeinTemp
Bzw. unter Linux:
[Programm]
TempDir=$HOME\MeinTemp
Ich lese mit TIniFile und ReadString diesen Wert ein in eine Variable vom Typ "String". Damit ist das ganze UTF8 Codiert.
Nun möchte ich eine Lazarus-Funktion aufrufen, die mir diese Environment-Variablen extrahiert und ich als String den absoluten Pfad stehen habe, als UTF8.
Wenn andere Funktionen eine andere Codierung benötigen, dann wandle ich das, damit habe ich keine Probleme.
So wie Du beschrieben hast, zu Fuß das machen, wäre zwar möglich, aber ich denke unter Linux ist das ersetzen etwas schwieriger, da man nicht genau weiß wann nun die Variable zu Ende ist, denn es gibt nur eine eindeutige Start-Kennung mit "$". Daher die Frage, gibt es eine fertige Funktion, die ich nur aufrufen brauche, so wie unter Windows?
Vielen Dank für die Infos.
Gruß Markus.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: ExpandEnvironmentStrings Plattformübergreifend?
MmVisual hat geschrieben:Ich lese mit TIniFile und ReadString diesen Wert ein in eine Variable vom Typ "String". Damit ist das ganze UTF8 Codiert.
Das ist nur UTF8-kodiert, wenn du das in UTF-8 hineinschreibst; TIniFile oder der Typ String wandelt da überhaupt nichts um.
MmVisual hat geschrieben:So wie Du beschrieben hast, zu Fuß das machen, wäre zwar möglich, aber ich denke unter Linux ist das ersetzen etwas schwieriger, da man nicht genau weiß wann nun die Variable zu Ende ist, denn es gibt nur eine eindeutige Start-Kennung mit "$". Daher die Frage, gibt es eine fertige Funktion, die ich nur aufrufen brauche, so wie unter Windows?
Soweit ich weiß, gibts keine fertige Funktion. Bei StringReplace() ist es aber auch egal, ob die Variable überhaupt im String vorkommt oder nicht. Wenn du nur bestimmte Umgebungsvariablen ersetzen möchtest, ist das auch nicht so zeitraubend.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
Ich kann mit vostellen, dass wenn eine Systemvariable $VARAA und eine zweite $VARAAA heißt und im String der INI das steht: "$VARAAAAAA", welche Variable ist dan richtig? $VARAA oder $VARAAA?
Also ich weiß jetzt nicht nach welcher Regel Linux das Handhabt. Oder bleiben solche Dinge dem Zufall überlassen?
Also ich weiß jetzt nicht nach welcher Regel Linux das Handhabt. Oder bleiben solche Dinge dem Zufall überlassen?
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: ExpandEnvironmentStrings Plattformübergreifend?
MmVisual hat geschrieben:Ich kann mit vostellen, dass wenn eine Systemvariable $VARAA und eine zweite $VARAAA heißt und im String der INI das steht: "$VARAAAAAA", welche Variable ist dan richtig? $VARAA oder $VARAAA?
Also ich weiß jetzt nicht nach welcher Regel Linux das Handhabt. Oder bleiben solche Dinge dem Zufall überlassen?
Die Variable geht immer bis zum nächsten Trennzeichen; wobei ich jetzt nicht genau weiß, was der POSIX-Standard vorschreibt.
Also bei "$VARAAAA/abc" wäre die Variable also $VARAAAA; daher musst du immer die längste Variable zuerst ersetzen. Alternativ könnte man auch darüber streiten, wie man denn $GDM_LANG und $GDMSESSION auseinander hält -- beide beginnen schließlich mit $GD...
Gegenfrage: Welche Variablen mit diesen Namen kennst du/hast du auf deinem System?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
Gegenantwort: Ich bin Windowsprogrammierer und habe von Linux nur sehr begrenzt Ahnung. Nur kompilliere ich meine Exe auch unter Linux und habe ein paar Kleinigkeiten dafür angepasst.
Nun möchte jemand gerne ein .deb Paket schnüren und dazu waren ein paar INI-Einträge erforderlich, die auf z.B. $HOME verweisen. Aber was die breite Masse der User so anstellt kann ich schlecht abschätzen. Daher wollte ich erst mal abschätzen/nachfragen wie das unter Linux denn richtig geht.
Erst mal die längste Variable nehmen, ich denke das ist ein gangbarer Weg und auch für jedermann verständlich dokumentierbar. Wenn das Ergebnis demjenigen dann nicht gefällt, so muss er eben eine andere Environment-Variable machen.
Falls jemand doch eine Linux-Funktion kennt, dann gerne noch posten.
Danke, Gruß Markus.
Nun möchte jemand gerne ein .deb Paket schnüren und dazu waren ein paar INI-Einträge erforderlich, die auf z.B. $HOME verweisen. Aber was die breite Masse der User so anstellt kann ich schlecht abschätzen. Daher wollte ich erst mal abschätzen/nachfragen wie das unter Linux denn richtig geht.
Erst mal die längste Variable nehmen, ich denke das ist ein gangbarer Weg und auch für jedermann verständlich dokumentierbar. Wenn das Ergebnis demjenigen dann nicht gefällt, so muss er eben eine andere Environment-Variable machen.
Falls jemand doch eine Linux-Funktion kennt, dann gerne noch posten.
Danke, Gruß Markus.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
Ich habe mal was geschrieben. Habe ich was vergessen, oder könnte man es besser (einfacher/effizienter) machen?
Diese Funktion erkennt Windows und Linux-Variablen. Allerdings habe ich das unter Linux jetzt noch nicht getestet.
Gruß Markus
PS: Kann der Code jemand nach FPC/Sysutils.pp einpflegen?
Diese Funktion erkennt Windows und Linux-Variablen. Allerdings habe ich das unter Linux jetzt noch nicht getestet.
Code: Alles auswählen
< neuer Code im nächsten Postiong von mir >
Gruß Markus
PS: Kann der Code jemand nach FPC/Sysutils.pp einpflegen?
Zuletzt geändert von MmVisual am Di 1. Mär 2011, 07:07, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: ExpandEnvironmentStrings Plattformübergreifend?
Das aufspalten am Gleichheitszeichen kann die StringList alleine machen (Names, Values und NameValueSeparator).
Man könnte annehmen, dass auf einer Plattform entweder %...% oder $... als Variablenname verwendet wird; das würde einiges an Effizienz bringen, wenn nicht immer nach beiden gesucht werden muss.
Man könnte annehmen, dass auf einer Plattform entweder %...% oder $... als Variablenname verwendet wird; das würde einiges an Effizienz bringen, wenn nicht immer nach beiden gesucht werden muss.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
Hab ich rein gemacht:
Noch die Änderung: Die Windows-Codierung mit %..% wird mit "rfIgnoreCase" geprüft.
Edit: Habe das grad mit Linux getestet, klappt prima! Es steht somit nichts mehr im Wege das in die FPC-Sourcen mit auf zu nehmen.
Code: Alles auswählen
Function ExpandEnvironmentString(s: String): String;
Var i, k, m: Integer;
sl: TStringList;
s2: String;
b, bP, bD: Boolean;
Begin
Result := s;
bP := Pos('%', s) > 0;
bD := Pos('$', s) > 0;
If Not(bP Or bD) Then // Nichts zu konvertieren
Exit;
sl := TStringList.Create;
k := GetEnvironmentVariableCount - 1;
For i := 0 To k Do // Alle Variablen in eine Liste merken
Begin
s2 := GetEnvironmentStringUTF8(i);
If Length(s2) >= 2 Then
If s2[1] <> '=' Then
Begin
If bD Then
Begin
m := Pos('=',s2) - 1;
sl.AddObject(s2, TObject(m));
End Else sl.Add(s2);
end;
end;
If bD Then // Nur bei Env-String mit '$' drin.
Repeat // Tauschen-Listen-Einträge, so dass die längsten Env-Strings zu Anfang stehen
b := True;
For i := 0 To sl.Count - 2 Do
Begin
If Integer(sl.Objects[i]) < Integer(sl.Objects[i + 1]) Then
Begin
b := False;
sl.Exchange(i, i + 1);
end;
end;
Until b;
m := 0;
Repeat // Durchlaufe so oft bis alle Env-Variablen aufgelöst sind
For i := 0 To sl.Count - 1 Do
Begin
If bP Then
Result := StringReplace(Result, '%' + sl.Names[i] + '%', sl.ValueFromIndex[i], [rfReplaceAll, rfIgnoreCase]);
If bD Then
Result := StringReplace(Result, '$' + sl.Names[i], sl.ValueFromIndex[i], [rfReplaceAll]);
end;
Inc(m);
If m > sl.Count - 2 Then break; // Max Durchläufe
b := True; // Teste auf weitere Env-Werte im String
If bP Then
Begin
i := Pos('%', Result);
If i > 0 Then b := PosEx('%', Result, i + 1) <= 0;
end;
If bD And b Then b := Pos('$', Result) <= 0;
Until b;
sl.Free;
end;
Noch die Änderung: Die Windows-Codierung mit %..% wird mit "rfIgnoreCase" geprüft.
Edit: Habe das grad mit Linux getestet, klappt prima! Es steht somit nichts mehr im Wege das in die FPC-Sourcen mit auf zu nehmen.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: ExpandEnvironmentStrings Plattformübergreifend?
MmVisual hat geschrieben:Edit: Habe das grad mit Linux getestet, klappt prima! Es steht somit nichts mehr im Wege das in die FPC-Sourcen mit auf zu nehmen.
Ich habe mir mal erlaubt, das ganze hinsichtlich der Lesbarkeit zu optimieren:
Code: Alles auswählen
{$IFDEF windows}
const
ENV_PREFIX = '%';
ENV_POSTFIX = '%';
{$ELSE}
const
ENV_PREFIX ='$';
ENV_POSTFIX = '';
{$ENDIF}
function ExpandEnvironmentStrings(const s: String; IgnoreCase: Boolean = True): String;
var
envs: TStringList;
aEnvValue: String;
aEnvName: String;
flags: TReplaceFlags;
i: Integer;
begin
Result := s;
if Pos(ENV_PREFIX, Result) = 0 then exit;
if IgnoreCase then
flags := [rfReplaceAll, rfIgnoreCase]
else
flags := [rfReplaceAll];
envs := TStringList.Create;
envs.Sorted := ENV_POSTFIX = '';
for i := GetEnvironmentVariableCount - 1 downto 0 do
envs.Add(GetEnvironmentString(i));
for i := envs.Count - 1 downto 0 do
begin
envs.GetNameValue(i, aEnvName, aEnvValue);
Result := StringReplace(Result, ENV_PREFIX+aEnvName+ENV_POSTFIX, aEnvValue, flags);
if Pos(ENV_PREFIX, Result) = 0 then break;
end;
envs.Destroy;
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
Hallo Socke,
Vielen Dank, sieht gut aus.
Was ist es möglich, dass in einer ENV Variable eine weitere mit drin ist?
%WERT1% = Hallo%WERT2%gugus
%WERT2% = Mein
Dann würde im Ergebnis immer noch %WERT2% drin stehen, da meine For-Schleife noch in ein Repeat gekapselt ist werden solche Verschachtelungen abgefangen. Bei Dir jetzt nicht.
Gruß Markus
PS: Ich bräuchte eine Funktion, bei der ein und die selbe INI-Datei mit den ENV-Werten unter Linux und Windows gleichermassen funktioniert, daher frage ich in meiner Routine beides einfach ab. Die Sortierung ist bei Dir eleganter gelöst.
Vielen Dank, sieht gut aus.
Was ist es möglich, dass in einer ENV Variable eine weitere mit drin ist?
%WERT1% = Hallo%WERT2%gugus
%WERT2% = Mein
Dann würde im Ergebnis immer noch %WERT2% drin stehen, da meine For-Schleife noch in ein Repeat gekapselt ist werden solche Verschachtelungen abgefangen. Bei Dir jetzt nicht.
Gruß Markus
PS: Ich bräuchte eine Funktion, bei der ein und die selbe INI-Datei mit den ENV-Werten unter Linux und Windows gleichermassen funktioniert, daher frage ich in meiner Routine beides einfach ab. Die Sortierung ist bei Dir eleganter gelöst.
EleLa - Elektronik Lagerverwaltung - www.elela.de
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: ExpandEnvironmentStrings Plattformübergreifend?
MmVisual hat geschrieben:Was ist es möglich, dass in einer ENV Variable eine weitere mit drin ist?
%WERT1% = Hallo%WERT2%gugus
%WERT2% = Mein
Dann würde im Ergebnis immer noch %WERT2% drin stehen, da meine For-Schleife noch in ein Repeat gekapselt ist werden solche Verschachtelungen abgefangen. Bei Dir jetzt nicht.
Wenn du für die rekursiven Variablen zuständig bist, bist du auch dafür zuständig die Rekursion wieder aufzulösen. Zumal du dir damit auch ganz einfach Endlosschleifen einhandeln kannst.
MmVisual hat geschrieben:PS: Ich bräuchte eine Funktion, bei der ein und die selbe INI-Datei mit den ENV-Werten unter Linux und Windows gleichermassen funktioniert, daher frage ich in meiner Routine beides einfach ab.
Umgebungsvariablen sind per Definition abhängig von der Umgebung. Um plattformunabhängig zu bleiben, wirst du vorher eine Normalisierung durchführen müssen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 1466
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
- CPU-Target: 32/64Bit
Re: ExpandEnvironmentStrings Plattformübergreifend?
> Zumal du dir damit auch ganz einfach Endlosschleifen einhandeln kannst.
Ja, deshalb hab ich einen Zähler drin, wenn das so aussieht dass es Endlos wird, dann BREAK;
(Den Zähler könnte ich auch optimieren indem ich den letzten String vergleiche, bei keiner Änderung gabs nichts zu konvertieren, bzw. die % $ Variable existiert nicht im System)
Um das Lazarus-Tauglich zu machen und in die FPC Sourcen auf zu nehmen ist deine Variante sicher besser geeignet
Meine Exe kompiliere ich unter Linux und Windows. Ich kann die SQLite Datenbank sowie die .so und .dll sowie die zwei EXE auf einen USB Stick kopieren und habe dann einen Stick, bei dem die Datenbank/das Programm sowohl unter Linux als auch unter Windows auf jedem Rechner ohne installation funktioniert.
Ist eine coole Sache.
Hier hab ich das mal vorgestellt:
viewtopic.php?f=11&t=4107
Ich nutze das auch als Warenlager, daher sollte das Programm möglichst Kriesentauglich sein, also problemlos mit USB Stick funktionieren können.
Edit: Hier ist meine geänderte Linux/Windows Kombi Variante, angepasst mit deinen besserungen:
Ja, deshalb hab ich einen Zähler drin, wenn das so aussieht dass es Endlos wird, dann BREAK;
(Den Zähler könnte ich auch optimieren indem ich den letzten String vergleiche, bei keiner Änderung gabs nichts zu konvertieren, bzw. die % $ Variable existiert nicht im System)
Um das Lazarus-Tauglich zu machen und in die FPC Sourcen auf zu nehmen ist deine Variante sicher besser geeignet
Meine Exe kompiliere ich unter Linux und Windows. Ich kann die SQLite Datenbank sowie die .so und .dll sowie die zwei EXE auf einen USB Stick kopieren und habe dann einen Stick, bei dem die Datenbank/das Programm sowohl unter Linux als auch unter Windows auf jedem Rechner ohne installation funktioniert.
Ist eine coole Sache.
Hier hab ich das mal vorgestellt:
viewtopic.php?f=11&t=4107
Ich nutze das auch als Warenlager, daher sollte das Programm möglichst Kriesentauglich sein, also problemlos mit USB Stick funktionieren können.
Edit: Hier ist meine geänderte Linux/Windows Kombi Variante, angepasst mit deinen besserungen:
Code: Alles auswählen
Function ExpandEnvironmentString(s: String): String;
Var i, k: Integer;
sl: TStringList;
s2: String;
bP, bD: Boolean;
Begin
Result := s;
bP := Pos('%', s) > 0;
bD := Pos('$', s) > 0;
If Not(bP Or bD) Then Exit; // Nichts zu konvertieren
sl := TStringList.Create;
sl.Sorted := bD;
For i := GetEnvironmentVariableCount - 1 DownTo 0 Do // Alle Variablen in eine Liste merken
Begin
s2 := GetEnvironmentStringUTF8(i);
If Length(s2) >= 2 Then
If s2[1] <> '=' Then // Bei Windows kommt sowas auch vor, daher wegoptimieren
sl.Add(s2);
end;
k := 0;
Repeat // Durchlaufe so oft bis alle Env-Variablen aufgelöst sind
s2 := Result;
For i := sl.Count - 1 DownTo 0 Do
Begin
If bP Then
Begin
Result := StringReplace(Result, '%' + sl.Names[i] + '%', sl.ValueFromIndex[i], [rfReplaceAll, rfIgnoreCase]);
If Pos('%', Result) = 0 Then bP := False;
end;
If bD Then
Begin
Result := StringReplace(Result, '$' + sl.Names[i], sl.ValueFromIndex[i], [rfReplaceAll]);
If Pos('$', Result) = 0 Then bD := False;
end;
If Not(bP Or bD) Then Break;
end;
If Not(bP Or bD) Then Break;
If SameText(s2, Result) Then Break; // % $ nicht konvertierbar, da im System nicht vorhanden
Inc(k);
If k > sl.Count - 2 Then Break; // Max Durchläufe
Until True;
sl.Free;
end;
EleLa - Elektronik Lagerverwaltung - www.elela.de