Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#14

Re: Umgebungsvariablen langfristig setzen

  Alt 11. Apr 2007, 12:46
Zitat von Christian Seehase:
reicht es Dir die Umgebungsvariable im Parent-Prozess zu setzen, so dass Du sie aus einem eigenen Konsolenprogramm heraus für die aufrufende Konsole setzen kannst?
Das wäre natürlich ideal.

Zitat von Olli:
Mir erscheint es sinnvoll, wenn du mal verraetst, was du erreichen willst
ich hab mir sozusagen ein kleines Programm erstellt, welches global eine Variable mit einem Installationsverzeichnis erstellt, so daß dieses auch von Batchdateien genutzt werden kann.

Für kleine Tools wäre es schon praktisch, wenn man da mit 'ner winzigen BatchFile arbeiten könnte, anstatt da gleich ein rießiges Setup erstellen zu müssen.

Tja, da es aber sein kann, daß dieses Verzeichnis noch nicht eingerichtet ist, wird halt von den "Setup"-Scripten vorher diese Prgrämmchen versucht aufzurufen und nachdem dieses das Verzeichnis eingerichtet hat, bräuchte ich ja nach dessen aufruf dn Pfad in dem Script.

Zitat von Olli:
Ja das sind alle. Soweit ich weiss ueberschreiben deine Variablen die Systemvariablen (also bzgl. der Reihenfolge).
Das war schon klar, also:
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Session Manager\Environment
- HKEY_CURRENT_USER\Environment
- und dat Eigene
in der Reinfolge eingelesen (mit Überschreiben)
und zwischendurch noch einiges Anderes...

Nur ob die Reihenfolge so auch richtig ist, war ich mir nicht ganz sicher. (abgesehn daß dieses nicht alles ist ... siehe weiter unten)

Zitat von Olli:
Nur beim Neustart eines Programms und Uebergabe der Umgebung.
Bei einem Programm gibt es ja Wege dieses zu machen aber ein Befehlsscript samt CMD aus sich selber raus neu zu starten wird wohl schwer.

Wenn ich nun innerhalb des Scripts CMD und das Script selber neu starte, dann wird da leider auch nur wieder nur der "alte" EnviromentBlock weitergegeben.
Code:
%ComSpec% /c %0

Zitat von Olli:
Die Frage verstehe ich nicht. Lokal ueberschreibt global. Wo ist der Konflikt?
Da es ja so eh keine Möglichkeit gibt rauszufinden welche Variablen/Werte von der Anwendung selber definiert wurden und vorallem welche nicht erneuert werden dürfen, bin ich da 'nen anderen/einfachen Weg gegangen.

Der Konflikt lag eigentlich mehr darin was sich nun innerhalb des Programms geändert hat und möglicher Weise bei einem Update nicht geändert werden dürfte....


Hab gestern abend mal angefangen 'ne winzige Klasse zu erstellen, welche den EnviromentBlock updatet.
Und dort eine Liste eingebaut, wo Werte registriert werden können, welche nicht geändert werden sollen.


Da sind dann nochmals die "bekannten" Funktionen zum Setzen/Auslesen der Umgebungsvariablen drin.
Die WinAPIs können aber dennoch genutzt werden, allerdings müßten dann über ReloadEnvironmentStrings(False) die geänderten Werte eingelesen werden.

Die Prozedur zum Updaten "ReloadEnvironmentStrings" kennt da 2 Varianten:
True=aktuelles aus'm System auslesen
False=aktuellen Enviromentblock des Programms auslesen (falls z.B. irgendwo im Programm direkt über die WinAPI was geändert wurde ... damit die Werte in der StringList "EnvironmentStrings" auch stimmen)

ReloadEnvironmentStrings wird über WM_SETTINGCHANGE und über Button1 [Reload] ausgeführt.


Soweit scheint es schonmal zu gehn ... nur fehlen bisher nach dem Reload noch ein Paar der Werte, also HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Session Manager\Environment und HKEY_CURRENT_USER\Environment ist nicht alles.

Folgendes fehlt bei mir noch:
Zitat:
ALLUSERSPROFILE=C:\Dokumente und Einstellungen\All Users
APPDATA=C:\Dokumente und Einstellungen\Frank\Anwendungsdaten

CLIENTNAME=Console
CommonProgramFiles=C:\Programme\Gemeinsame Dateien
COMPUTERNAME=FRANK

DELPHI=c:\programme\borland\delphi7

HOMEDRIVE=C:
HOMEPATH=\Dokumente und Einstellungen\Frank
LANGUAGE=English
LOGONSERVER=\\FRANK

ProgramFiles=C:\Programme

SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\WINDOWS

USERDOMAIN=FRANK
USERNAME=Frank
USERPROFILE=C:\Dokumente und Einstellungen\Frank
"DELPHI" ist klar: dieses scheint eine Variable zu sein, welche das Programm aus dem EnviromentBlock von Delphi mitbekommt.
Denn diese ist nur vorhanden, wenn über den Debugger gestartet wurde.

Und damit alles stimmt, wäre es ja besser, wenn ich nun die selben Quellen nutze, welche dafür original auch erwendet wurden.


Ach ja: Eigentlich wollt ich erst über Application.OnMessage gehn, da sich dort die Klasse hätte selber einklinken könne ... nur kommt da kein WM_SETTINGCHANGE an.
Also mußte ich sie von Hand in das Hauptfenstern schleußen.
Procedure WMSettingChange(Var Msg: TMessage); Message WM_SETTINGCHANGE;


Zitat von Olli:
Hast du es mal getestet? Sollte doch gehen, denn eigentlich sollte das auf dem Environment-Block des Prozesses basieren.

SetEnvironmentVariable hilft doch dann. Und die Aenderung wird auch an Kindprozesse weitergegeben.
Also im eigenem Programm verwenden und Weitervererben geht ... nur halt nicht rückwärts.



Zitat von Christian Seehase:
Wenn ich, um Zuge einer Batchverarbeitung, eine Umgebungsvariable so setzen will, dass sie nach meinem Programm zur Verfügung steht, sieht MS vor, dass man eine Batchdatei mit dem entsprechenden Set-Kommando erstellt, die dann nach dem Programm aufgerufen werden soll.
Na sowas klingt doch auch nicht schlecht.



PS: weiß zufällig jemand, was der 1. Eintrag '=::=::\' in Windows.GetEnvironmentStrings zu bedeuten hat?
Name = ""
Value = "::=::\"
Der ist immer vorhanden und ging auch nicht zu löschen (SetEnvironmentVariable).
(hab ihn, oder besser gesagt alles was keinen Namen hat, einfach mal ignoriert)
Wer sowas nicht ausblenden will, der kann mal dieses auskommentieren/entfernen:
If Pos('=', P2) > 1 Then
PSS: falls es keinem augefallen ist ... mir fiel zufällig eine praktische/schöne Umkehrfunktion zu ExpandEnvironmentStrings in die Händchen.





Oder wie wäre ein anderer "einfacher" Ansatz, welcher aber nur innerhalb eines selbstgeschriebenen Programmes und den nachfolgenden Kindprozessen geht.

Das Programm startet eine neue Instanz von sich selber (ohne Übergabe des eigenen EnviromentBlocks), daber dafür mit 'nem netten Parameter.
Diese Instanz schickt eine Kopie des eigenen EnviromentBlocks an die erste Instanz und beendet sich wieder.
In der Ursprungsinstanz wird dann der empfangene Block einfach reingeladen.

> würde zumindestens das "eigenhändige" Zusammensuchen der nötigen Daten ersparen.




Anhang:
Project1 = ein Testporgramm mit der Updateklasse
InitializeDefaultDir = das Programm welches die Umgebungsvariable erstellt
und im FileSplitter die BatchFiles, welche diese Variable nutzen.

- die zu erwartenden Registry einträge sind aus den .reg-Dateien zu ersehen und natürlich er eintrag unter HKEY_CURRENT_USER\Environment ... wo dann auch das Installationsverzeichnis herkommt
Installationsverzeichnis is auch noch über _test.cmd rauszubekommen ^^
Angehängte Dateien
Dateityp: 7z archive_146.7z (488,9 KB, 12x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat