wie setzt man Umgebungsvariablen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
alfware17
Beiträge: 98
Registriert: Di 14. Dez 2010, 23:27

wie setzt man Umgebungsvariablen

Beitrag von alfware17 »

In dem folgenden, bereits funktionierenden Code

Code: Alles auswählen

Unit logik;

{$mode ObJFPC}

interface

const daten_slash = {$IFDEF Linux} '/' {$ELSE} '\' {$ENDIF};
      daten_pfad: String = '';
      daten_database: String = 'dbZitate.s3db';
      daten_dateiname: String = 'dbZitate.s3db';
      daten_dateilokal: Boolean = true;
      still: Boolean = false;

procedure sucheDatei(sDateiname: string);
procedure testEnv(value:String);

implementation

uses SysUtils, Dos {$IFNDEF Linux}, Registry {$ENDIF};

function addPfad(eins, zwei: string):string;
var temp: string;
begin
   temp:=eins;
   if (temp <> '') and
      (temp[length(temp)] <> daten_slash) and
      (zwei <> '')
      then temp:=temp+daten_slash;
   temp:=temp+zwei;
   Result:=temp;
end;

{$IFNDEF Linux}
function GetRegZitadell(Key: string):string;
var Registry: TRegistry;
    tempdir, temppfad: string;
begin
   Registry := TRegistry.Create; tempdir:='';
   try
      Registry.RootKey := HKEY_LOCAL_MACHINE;
      if Registry.OpenKeyReadOnly('\SOFTWARE\'+Key)
         then tempdir:= Registry.ReadString('');
   finally
      Registry.Free;
   end;
   temppfad:=addpfad( tempdir, daten_database );
   if DirectoryExists(tempdir) and FileExists(temppfad)
      then result:=tempdir else result:='';
end;
{$ENDIF}

function GetEnvZitadell(Key: string):string;
var tempdir, temppfad:string;
begin
   tempdir:=GetEnvironmentVariable(Key);
   temppfad:=addpfad( tempdir, daten_database );
   if DirectoryExists(tempdir) and FileExists(temppfad)
      then result:=tempdir else result:='';
end;

procedure SetEnvZitadell(Key, Value: string);
begin
   SetEnvironmentVariable(Key, Value);
end;

function GetHomeZitadell(Extension: string):string;
var tempdir, temppfad: string;
begin
   tempdir:=GetUserDir;
   tempdir:=addpfad( tempdir, Extension );
   temppfad:=addpfad( tempdir, daten_database );
   if DirectoryExists(tempdir) and FileExists(temppfad)
      then result:=tempdir else result:='';
end;

function GetLwUserDirZitadell(Lw, Key: string):string;
var tempdir, temppfad:string;
begin
   tempdir:=addpfad( Lw, Key );
   temppfad:=addpfad( tempdir, daten_database );
   if DirectoryExists(tempdir) and FileExists(temppfad)
      then result:=tempdir else result:='';
end;

function GetUserDirZitadell(Key: string):string;
var temp:string;
begin
   {$IFDEF LINUX}
      temp:=GetLwUserDir('', Key)
   {$ELSE}
      temp:=GetLwUserDirZitadell('c:', Key);
      if temp = '' then temp:=GetLwUserDirZitadell('C:', Key);
   {$ENDIF};
   result:=temp;
end;

//0:  Registry  (* nur Windows *)
//    GetRegZitadell
//    Registry \SOFTWARE\Alfware\Zitadell und ALFWARE/ZITADELL und alfware/zitadell
//    Groß-/ Klein-Schreibung kann eigentlich entfallen
//
//1:  Environment-Variable Zitadell
//    GetEnvZitadell
//    ENV   Zitadell und ZITADELL und zitadell
//
//2:  Home (Eigene Dateien)
//    GetHomeZitadell
//    USER/   . und /Zitadell und /documents und /Dokumente und /documents/Zitadell und /Dokumente/Zitadell
//    USER/         /ZITADELL und /documents/ZITADELL und /Dokumente/ZITADELL
//    USER/         /zitadell und /documents/zitadell und /Dokumente/zitadell
//
//3:  User
//    GetUserDirZitadell
//    Win: c:/  C;/  /Zitadell und /Bernd/Zitadell und bernd/Zitadell
//                   /ZITADELL und /Bernd/ZITADELL und bernd/ZITADELL
//    Linux ohne     /zitadell und /Bernd/zitadell und bernd/zitadell
//

procedure zitadellPfad(psteuer: Integer);
begin
   if daten_pfad <> '' then exit;
   case psteuer of
   {$IFNDEF Linux}
   0: begin
         (* Registry *)
         if daten_pfad = '' then daten_pfad:= GetRegZitadell('Alfware\Zitadel1');
         if daten_pfad = '' then daten_pfad:= GetRegZitadell('ALFWARE\ZITADELL');
         if daten_pfad = '' then daten_pfad:= GetRegZitadell('alfware\zitadell');
      end;
   {$ENDIF}
   1: begin
         (* Environment Variable *)
         if daten_pfad = '' then daten_pfad:= GetEnvZitadell('Zitadell');
         if daten_pfad = '' then daten_pfad:= GetEnvZitadell('ZITADELL');
         if daten_pfad = '' then daten_pfad:= GetEnvZitadell('zitadell');
      end;
   2: begin
         (* Home-Dir *)
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell('');
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell('Zitadell');
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell('ZITADELL');
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell('zitadell');
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell('documents');
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell('Dokumente');
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell(addPfad('documents','Zitadell'));
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell(addPfad('Dokumente','Zitadell'));
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell(addPfad('documents','ZITADELL'));
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell(addPfad('Dokumente','ZITADELL'));
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell(addPfad('documents','zitadell'));
         if daten_pfad = '' then daten_pfad:= GetHomeZitadell(addPfad('Dokumente','zitadell'));
      end;
   3: begin
         (* User-Dir *)
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell('Zitadell');
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell(addPfad('Bernd','Zitadell'));
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell(addPfad('bernd','Zitadell'));
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell('ZITADELL');
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell(addPfad('Bernd','ZITADELL1'));
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell(addPfad('bernd','ZITADELL1'));
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell('zitadell');
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell(addPfad('Bernd','zitadell'));
         if daten_pfad = '' then daten_pfad:= GetUserDirZitadell(addPfad('bernd','zitadell'));
      end;
   else
   end;
end;

procedure sucheDatei(sDateiname: string);
var vorhanden: boolean;
begin
   Writeln('Start sucheDatei');
   zitadellPfad(0);
   zitadellPfad(1);
   zitadellPfad(2);
   zitadellPfad(3);
   vorhanden:= false;
   if sDateiname <> '' then begin
      daten_dateiname:= sDateiname;
      if fileExists( daten_dateiname ) then begin
         daten_dateilokal:= true;
         if not still then Writeln( 'Dateiname: ' + daten_dateiname + ' gefunden' );
         vorhanden:= true;
      end;
      if ( not vorhanden ) and fileExists( addPfad(daten_pfad, daten_dateiname) ) then begin
         daten_dateilokal:= false;
         if not still then Writeln( 'Dateiname: ' + addPfad(daten_pfad, daten_dateiname)+ ' gefunden' );
         vorhanden:= true;
      end;
   end;
   if daten_pfad = '' then Writeln('Nichts gefunden?');
   Writeln('Beendet sucheDatei');
end;

procedure testEnv(value: string);
begin
   SetEnvZitadell('zitadell','Testwert');
   Writeln(GetEnvZitadell('zitadell1'));
end;

begin
end.
frage ich wenn auch etwas umständlich würdet Ihr sagen Systemvariablen, Registry und ein paar Directories ab, ob da eine bestimmte Datei ist, die Reihenfolge ist wichtig.

Nun wollte ich die Systemvariable auch setzen, in einigen Google-Suchen wie auch von ChatGPT wird angegeben, es gäbe eine

Code: Alles auswählen

SetEnvironmentVariable()
Methode in den Sysutils.
Leider compiliert das nicht und ich finde die Methode auch nicht in der Sysutils-Übersicht. Warum gibt es kein Gegenstück zur

Code: Alles auswählen

GetEnvironmentVariable()
?

Ich hatte für das Lesen auch erst GetEnv() von Pascal benutzt, ok den (für mich marginalen) Unterschied habe ich gelesen. Allerdings finde ich auch kein SetEnv() oder so. Wie macht man das denn?

Und wenn Ihr ganz lieb seid, schaut Ihr Euch bitte auch noch mal mein Registry-Auslesen an. Das wäre nämlich die nächste Frage - wie schreibe ich den bestimmten Schlüssel in der Registry. Ja ich weiß, selber rumschreiben in der Registry ist gefährlich - aber irgendwie muß man da ja Werte reinbekommen können.
Ich hatte vor Jahren mal eine Programm-Installationsroutine (EasySetup), das hat mir beide Aufgaben (Registry und Umgebungsvariable setzen) erledigt. Leider funktioniert das nicht mehr(?) unter Win7/10/11 und somit hatte ich die Idee, schnell selbst ein Dienstprogramm zu schreiben, was eben das macht. Oder gibt es solche kleinen Programme, Lazarus schreiben wäre natürlich viel besser.

Benutzeravatar
theo
Beiträge: 10334
Registriert: Mo 11. Sep 2006, 19:01

Re: wie setzt man Umgebungsvariablen

Beitrag von theo »

Das wurde im Hauptforum mehrfach diskutiert:

https://forum.lazarus.freepascal.org/in ... ic=45987.0
https://forum.lazarus.freepascal.org/in ... ic=58314.0
etc.

Scheint nicht so eine gute Idee.

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 248
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: wie setzt man Umgebungsvariablen

Beitrag von h-elsner »

Install Routinen würde ich mit InnoSetup machen. Mit entsprechender Lernkurve kann das wohl alles, was man sich wünscht.
Ich habe allerdings schon sehr lange kein Installationsgeraffel mehr benutzt.

Gruß HE

Socke
Lazarusforum e. V.
Beiträge: 3155
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: wie setzt man Umgebungsvariablen

Beitrag von Socke »

alfware17 hat geschrieben:
Di 7. Nov 2023, 10:42
Und wenn Ihr ganz lieb seid, schaut Ihr Euch bitte auch noch mal mein Registry-Auslesen an. Das wäre nämlich die nächste Frage - wie schreibe ich den bestimmten Schlüssel in der Registry. Ja ich weiß, selber rumschreiben in der Registry ist gefährlich - aber irgendwie muß man da ja Werte reinbekommen können.
Siehe viewtopic.php?t=8018

Code: Alles auswählen

   Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY);
   try
      Registry.RootKey := HKEY_LOCAL_MACHINE;
      if Registry.OpenKey('\SOFTWARE\'+Key)
         then tempdir:= Registry.WriteString('Name', 'Wert');
   finally
      Registry.Free;
   end;
Für den ändernden Zugriff auf HKEY_LOCAL_MACHINE muss dein Programm ggf. als Admin gestartet werden.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

charlytango
Beiträge: 813
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz 2.2.6
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: wie setzt man Umgebungsvariablen

Beitrag von charlytango »

mein Post geht von der Annahme aus dass du "von außen" Einstellungen in einer Applikation machen möchtest.
zB Name der Datenbank etc.
alfware17 hat geschrieben:
Di 7. Nov 2023, 10:42
Ja ich weiß, selber rumschreiben in der Registry ist gefährlich - aber irgendwie muß man da ja Werte reinbekommen können.
Ich konnte nie die Begeisterung nachvollziehen alle Einstellungen für Programme und Betriebssystem in einer gemeinsamen Struktur zu verwalten. Das macht diese Struktur IMHO unhandlich und anfällig für Probleme die mit einer zerschossenen Registry einhergehen und immer wieder auch mal auftraten.
Ja, es gibt Argumente dafür, besonders in Unternehmensnetzwerken (meist mit personalisierten Desktops) aber wo immer es ging habe ich vermieden dass sich meine Programme ins OS graben.

Eine Datei (oder je nach Anwendung auch mehrere) im Programmverzeichnis (oder einem beliebigen anderen Verzeichnis) kann alle nötigen Einstellungen enthalten. Welches Format die hat (INI,XML,JSON oder irgendwas eigenes) ist für mich Geschmackssache. Wenn man die Einstellungen (zb gegen neugierige übermotivierte Benutzer) schützen will kann man diese Datei auch mehr oder weniger stark verschlüsseln.

Dazu in der Applikation eine Struktur schaffen um auf diese Einstellungsdaten überall im Programm zugreifen zu können.
Ich benutze dazu meistens ein Singleton-Objekt (dazu findest du hier im Forum einiges) das die Lese- und Schreibfunktionen sowie die Einstellungsdaten enthält. Ich verwende meistens TMemINI (für andere Formate vielleicht TXMLConfig oder TJSONConfig), das liest die gesamte Datei auf einmal ein und lässt sich wie eine INI-Datei im Speicher verwenden. Das ganze in eine Unit gepackt und du hast ein wiederverwendbares zuverlässiges Vehikel für deine Einstellungswerte.

Benutzeravatar
Ally
Beiträge: 255
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: wie setzt man Umgebungsvariablen

Beitrag von Ally »

Hallo,

anbei zwei Beispiele wie man Werte in der Windows-Registry oder einer Ini-Datei sichern und wieder einlesen kann.
Exemplarisch habe ich dazu die Fensterwerte für Position, Größe usw. verwendet.

Die Variante im XReg Ordner verwendet TRegistry.
TRegistry ist in Lazarus plattformübergreifend implementiert. ( https://wiki.freepascal.org/fcl-registry )
Ich habe eine kleine Unit dafür gebaut, die String, Integer, Boolean, etc. in die Registry schreiben und aus ihr lesen kann.
Und weil das Ganze plattformübergreifend ist, funktioniert es auch unter Linux, dort werden Registry-Zugriffe automatisch im Ordner .config in einer entsprechenden XML-Datei gespeichert.
Vorteil: die Programmeinstellungen liegen BS-spezifisch an der "richtigen" Stelle und sind immer zugänglich.

Die Variante im Ordner XIni verwendet TIniFile.
Mit dieser Variante kann man eine Ini-Datei in einen beliebigen Ordner schreiben.
Man muss sich aber auch darum kümmern, dass man dort, wo man hinschreiben möchte, auch Schreibrechte hat.


Gruß Roland
Dateianhänge
RegIni.zip
(12.2 KiB) 6-mal heruntergeladen

Soner
Beiträge: 608
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: wie setzt man Umgebungsvariablen

Beitrag von Soner »

Die SetEnvironmentVariable-Funktion gibt es in Windows, du musst einfach "uses windows;" hinzufügen.

Wenn du aber in deinem Programm nicht die komplette Windows-unit hinzufügen willst, dann kannst du es auch selbst definieren:

Code: Alles auswählen

function SetEnvironmentVariable(lpName, lpValue:PChar):longbool; external 'kernel32' name 'SetEnvironmentVariableA';

Antworten