VB Excel-Vba, Windows Umgebungsvariable setzen Set

Hallo Wissende,

wie kann ich in WindowsXP per VB, Excel-VBA, eine Umgebungsvariable setzen, ändern, löschen?

Ich habe in Vba eine Schleife gebaut, die mir alle gesetzten Umgebungsvariablen durch Msgbox Environ(x) anzeigt.

Nach diesen Namen/Werten habe ich dann in der Registry gesucht, sie sind da sehr verstreut, also keinesfalls eine einzige Auflistung.

Wie/wo füge ich da eine neue Umgebungsvariable hinzu oder ändere den Wert einer bestehenden?
Manuell geht es in Systemsteuerung–System—Erweitert…

Der Set-Befehl von Dos in einer Batch funktioniert nicht, bzw. nur temporär, wenn man eine cmd.exe Instanz aufruft nur solange wie diese Instanz läuft, d.h. in WinXP ist sie nicht auswertbar.

Gruß
Reinhard

Hallo Reinhard,

auch hier haben wir eine passende Lösung :wink:
Sicher kommt es darauf an ob du sie Systemweit oder Benutzerdefiniert setzen willst. Auch spielt es eine Rolle welches OS auf dem System läuft!
Ich poste Dir anbei mal eine kleine Function was genau dies macht :smile:
Die Umgebungsvariable ist dann für den lfd. Prozess gueltig!
Nutzt du stattdessen noch ein Win95 / 98 so kannst du die Autoexec.bat nutzen :wink:

Option explicit

Private Declare Function SetEnvironmentVariable \_ 
 Lib "kernel32" Alias "SetEnvironmentVariableA" ( \_ 
 ByVal EnvironmentVariableName As String, \_ 
 ByVal EnvironmentVariableValue As String \_ 
 ) As Long 

Public Function Set Umgebungsvariable(sName as String, Wert as String) as Boolean
Dim lResult as Long
lResult = SetEnvironmentVariable(sName,Wert)
Umgebungsvariable=cbool(lResult=0)
End Function

Möchtest du eine Umgebungsvariable ab ein NT basierenden OS setzen, so kannst du dich in der Registry an den Schluesseln bedienen / setzen.

HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment 

oder

HKEY\_CURRENT\_USER\Environment 

MfG Alex

Hallo Anno,

Sicher kommt es darauf an ob du sie Systemweit oder
Benutzerdefiniert setzen willst.

Eher das Letztere. Meine Idee ist, beim Start der Personl.xls von Excel überprüft ein Makro den Usernamen und setzt daraufhin eine Umgebungsvariable mit z.B. dem Abteilungsnamen.

Diesen Abteilungsnamen kann man dann mit Prozeduren in Exceldateien auslesen über Environ().

Also ist die Gültigkeit bzw. Gültigkeitsdauer dieser Umgebungsvariablen der ganze PC mit allen Anwendungen solange, bzw. sobald Excel läuft.
Wird der PC abgeschaltet, kann die Variable ruhig verschwinden.
Von anderen PCs aus wird sie nicht abgefragt, die haben dann ihre eigene Variable.

Auch spielt es eine Rolle welches OS auf dem System läuft!

Das aus Redmont(d), WinXP, natürlich wäre es mehr als schick wenn der Code auch auf allen BS ab Win98 läuft bis hin zu diesem Vistakram.

Ich poste Dir anbei mal eine kleine Function was genau dies
macht :smile:
Die Umgebungsvariable ist dann für den lfd. Prozess gueltig!

Was genau ist der laufende Prozess? Die Vba-Prozedur die die Umgebungsvariable setzt?
Die laufende Excelanwendung, das laufende Windows?

Nutzt du stattdessen noch ein Win95 / 98 so kannst du die
Autoexec.bat nutzen :wink:

Ja, WinXP beachtet die autoexec nicht.

Ich habe deinen Code lauffähig gemacht, aber die Variable wird nicht gesetzt, die Function liefert „Falsch“, also ist lResultat0:

Option Explicit
'
Private Declare Function SetEnvironmentVariable \_
Lib "kernel32" Alias "SetEnvironmentVariableA" ( \_
ByVal EnvironmentVariableName As String, \_
ByVal EnvironmentVariableValue As String \_
) As Long
'
Sub test()
MsgBox Set\_Umgebungsvariable("MeineVariable", "12345")
End Sub
'
Public Function Set\_Umgebungsvariable(sName As String, Wert As String) As Boolean
Dim lResult As Long
lResult = SetEnvironmentVariable(sName, Wert)
Set\_Umgebungsvariable = CBool(lResult = 0)
Dim x
For x = 1 To 60
 If Environ(x) Like "M\*" Then MsgBox Environ(x)
Next x
End Function

Möchtest du eine Umgebungsvariable ab ein NT basierenden OS
setzen, so kannst du dich in der Registry an den Schluesseln
bedienen / setzen.

Ich habe da Lücken, ist WinXP „ab ein NT basierenden OS“ ?
Vista ?

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment
oder
HKEY_CURRENT_USER\Environment

Sehe ich das richtig, ich kann die Variable für die „Local_Machine“ eintragen oder/und für den jeweiligen „User“!?

Gut, muß ich mal nach Registrierungsänderungscode googeln.

Kannst du nochmal schauen warum die Variable mit deinem Code nicht gesetzt wird? Danke.

Gruß
Reinhard

Hallo Wissende,

spricht was gegen VBA

Application.UserName

Hi Rakon,

spricht was gegen VBA

natürlich nicht :smile:

Application.UserName

guter Ansatz, aber ich will ja erstmal die Umgebungsvariable setzen, bzw. oder auch verändern, wie im alten Dos:
Set Path=%%Path%%;C:\MeinOrdner

Gruß
Reinhard

Soviel ich nun gelesen hab ist das nicht wie im DOS, XP etc arbeiten mit registry , dort bewahrt es seine sachen auf.
Die Enviroments die möglich sind zu ändern sind aber nur für den eigenen Prozess gültig.
Siehe : http://www.activevb.de/tipps/vb6tipps/tipp0421.html

Der rest ist nicht mit VBA zu realisieren.
Einige versuche wie es sonst gelöst werden könnte hab ich dort gefunden
http://www.codenewsgroups.net/group/microsoft.public…

Wobei dort auch steht das ein Registry Flush so einige sekunden dauern kann und das ist manchen nicht gerade so angenehm.

Also auslesen kein Problem, selber System global setzten grosses Problem, da wir nicht mehr im DOS sind sondern mit der Registry arbeiten müssen.

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Anno,

Hallo Reinhard,

Das aus Redmont(d), WinXP, natürlich wäre es mehr als schick
wenn der Code auch auf allen BS ab Win98 läuft bis hin zu
diesem Vistakram.

Ok, dann hast du aber mehr Aufwand :confused:
Unter Win9X und WinME kannst du das wie gesagt nur in der Autoexec.bat machen. Das erfordert aber einen Neustart :confused: Sprich, du muesstest erst das OS ermitteln und dann entsprechend reagieren. Das sollte aber kein Problem sein :smile: Wie man das macht, das weisst du?

Du kannst wie gesagt die Variablen Systemweit oder für den angemeldeten User setzen! Aber beim OS von Win9X oder WinMe kannst du sie nur Systemweit setzen!

Was genau ist der laufende Prozess? Die Vba-Prozedur die die
Umgebungsvariable setzt?
Die laufende Excelanwendung, das laufende Windows?

Damit meinte ich, das lfd. Programm. Also sprich Excel :smile: und alle durch Excel gestarteten Prozesse :smile:

Ja, WinXP beachtet die autoexec nicht.

Richtig

Ich habe deinen Code lauffähig gemacht, aber die Variable wird
nicht gesetzt, die Function liefert „Falsch“, also ist
lResultat0:

Ich habe mal was getippselt. Aber ist halt unter VB.

Option Explicit

Private Declare Function SetEnvironmentVariable \_
Lib "kernel32" Alias "SetEnvironmentVariableA" ( \_
ByVal EnvironmentVariableName As String, \_
ByVal EnvironmentVariableValue As String \_
) As Long

Private Const FORMAT\_MESSAGE\_FROM\_SYSTEM As Long = &H1000&
Private Const FORMAT\_MESSAGE\_IGNORE\_INSERTS As Long = &H200&
Private Const FORMAT\_MESSAGE\_MAX\_WIDTH\_MASK As Long = &HFF&
Private Const LANG\_USER\_DEFAULT As Long = &H400&
Private Declare Function FormatMessage \_
 Lib "kernel32" Alias "FormatMessageA" ( \_
 ByVal dwFlags As Long, \_
 ByRef lpSource As Any, \_
 ByVal dwMessageId As Long, \_
 ByVal dwLanguageId As Long, \_
 ByVal lpBuffer As String, \_
 ByVal nSize As Long, \_
 ByRef Arguments As Long \_
 ) As Long

Public Function APIErrorDescription(ByVal ErrLastDllError As Long) As String
Dim sBuffer As String
Dim lBufferLen As Long
 sBuffer = Space$(1024)
 lBufferLen = FormatMessage(FORMAT\_MESSAGE\_FROM\_SYSTEM Or FORMAT\_MESSAGE\_MAX\_WIDTH\_MASK Or FORMAT\_MESSAGE\_IGNORE\_INSERTS, ByVal 0&, ErrLastDllError, LANG\_USER\_DEFAULT, sBuffer, Len(sBuffer), 0)
 If lBufferLen \> 0 Then
 APIErrorDescription = Left$(sBuffer, lBufferLen)
 Else
 APIErrorDescription = "Unbekannter Fehler: &H" & Hex$(ErrLastDllError)
 End If
End Function

Private Function SetEnviron(sName As String, Wert As String, Optional ShowError As Boolean = True) As Boolean
Dim x As Long
 x = SetEnvironmentVariable(sName, Wert)
 If x 0 Then
 'Rückgabewert=1 -\> erfolgreich
 SetEnviron = True
 Else
 'Rückgabewert=0 -\> Fehlgeschlagen
 If ShowError Then MsgBox APIErrorDescription(Err.LastDllError)
 SetEnviron = False
 End If
End Function

Private Sub GetEnviron()
Dim i As Long
Dim strEnvironVars As String
 i = 1
 Do While LenB(Environ$(i)) \> 0
 strEnvironVars = strEnvironVars & Environ$(i) & vbNewLine
 i = i + 1
 Loop
 If LenB(strEnvironVars) \> 0 Then
 strEnvironVars = Left$(strEnvironVars, Len(strEnvironVars) - 2)
 End If
 MsgBox "Die folgenden Umgebungsvariablen sind definiert:" & vbNewLine & vbNewLine & \_
 strEnvironVars, \_
 vbInformation, \_
 "Definierte Umgebungsvariable"
End Sub

Private Sub Form\_Load()
 SetEnviron "Peter", "Alex"
 GetEnviron
End Sub

Er zeigt mir an das alles Fehlerfrei ausgefuehrt wird :smile:

Ich habe da Lücken, ist WinXP „ab ein NT basierenden OS“ ?
Vista ?

Richtig, ab Win2000 sind die OS NT Basierend :smile:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment
oder
HKEY_CURRENT_USER\Environment

Sehe ich das richtig, ich kann die Variable für die
„Local_Machine“ eintragen oder/und für den jeweiligen „User“!?

Genau. Aber wenn du sie eingetragen hast, so sind sie dem System noch nicht bekannt! Du musst Windows davon erst informieren!

Gut, muß ich mal nach Registrierungsänderungscode googeln.

Kannst du nochmal schauen warum die Variable mit deinem Code
nicht gesetzt wird? Danke.

ICh habe das gepostete Demo von mir bei mir mal probiert und da läuft es anstandslos durch!

Aber sei es drum. Ich poste Dir nochmal eine Function, die die gewuenschte Arbeit macht :smile: Ist unter VB getestet. Musst nur mal schauen wie du es umstricken musst damit es unter VBA läuft.
Hierbei werden die Variablen in der Registry gesetzt :wink:

Option Explicit

Private Const WM\_WININICHANGE As Long = &H1A&
Private Const WM\_SETTINGCHANGE As Long = WM\_WININICHANGE
Private Const SMTO\_ABORTIFHUNG As Long = &H2&
Private Const HWND\_BROADCAST As Long = &HFFFF&
Private Const KEY\_CREATE\_SUB\_KEY As Long = &H4&
Private Const KEY\_SET\_VALUE As Long = &H2&
Private Const REG\_SZ As Long = &H1&
Private Const REG\_OPTION\_NON\_VOLATILE As Long = &H0&
Private Const ERROR\_SUCCESS As Long = &H0&
Private Const VER\_PLATFORM\_WIN32\_NT As Long = &H2&

Private Enum REGISTRYKEYS
 HKEY\_CLASSES\_ROOT = &H80000000
 HKEY\_CURRENT\_USER = &H80000001
 HKEY\_LOCAL\_MACHINE = &H80000002
 HKEY\_USERS = &H80000003
 HKEY\_PERFORMANCE\_DATA = &H80000004
 HKEY\_CURRENT\_CONFIG = &H80000005
 HKEY\_DYN\_DATA = &H80000006
End Enum

Private Declare Function SetEnvironmentVariable \_
 Lib "kernel32" Alias "SetEnvironmentVariableA" ( \_
 ByVal EnvironmentVariableName As String, \_
 ByVal EnvironmentVariableValue As String \_
 ) As Long

Private Type OSVERSIONINFO
 dwOSVersionInfoSize As Long
 dwMajorVersion As Long
 dwMinorVersion As Long
 dwBuildNumber As Long
 dwPlatformId As Long
 szCSDVersion As String \* 128
End Type

Private Declare Function GetVersionEx \_
 Lib "kernel32" Alias "GetVersionExA" ( \_
 ByRef VersionInformation As OSVERSIONINFO \_
 ) As Long

Private Declare Function RegCreateKeyEx \_
 Lib "advapi32.dll" Alias "RegCreateKeyExA" ( \_
 ByVal hKey As Long, \_
 ByVal SubKey As String, \_
 ByVal Reserved As Long, \_
 ByVal Class As String, \_
 ByVal Options As Long, \_
 ByVal DesiredAccess As Long, \_
 ByVal SecurityAttributes As Long, \_
 ByRef hKeyResult As Long, \_
 ByRef Disposition As Long \_
 ) As Long

Private Declare Function RegSetValueEx \_
 Lib "advapi32.dll" Alias "RegSetValueExA" ( \_
 ByVal hKey As Long, \_
 ByVal ValueName As String, \_
 ByVal Reserved As Long, \_
 ByVal TypeOfValue As Long, \_
 ByRef Value As Any, \_
 ByVal SizeOfValue As Long \_
 ) As Long

Private Declare Function RegCloseKey \_
 Lib "advapi32.dll" ( \_
 ByVal hKey As Long \_
 ) As Long

Private Declare Function SendMessageTimeout \_
 Lib "user32" Alias "SendMessageTimeoutA" ( \_
 ByVal hWnd As Long, \_
 ByVal Message As Long, \_
 ByVal wParam As Long, \_
 ByRef lParam As Any, \_
 ByVal Flags As Long, \_
 ByVal Timeout As Long, \_
 ByRef Result As Long \_
 ) As Long

Public Function SetEnvironVar(ByVal VariableName As String, ByVal VariableValue As String, Optional ByVal Systemwide As Boolean = False) As Boolean
' VariableName: Name der neuen Umgebungsvariablen.
' VariableValue: Wert der neuen Umgebungsvariablen.
' Systemwide: Legt fest, ob eine Benutzer-Umgebungsvariable oder
' (nur WinNT) eine System-Umgebungsvariable erzeugt werden soll.
' TRUE: Es wird eine System-Umgebungsvariable erzeugt
' (hinreichende Rechte vorausgesetzt).
' FALSE: Es wird eine Benutzer-Umgebungsvariable erzeugt.
' Dieser Parameter hat unter Windows 9x/Me keine Wirkung.
' Rückgabewert: TRUE bei Erfolg, FALSE bei Misserfolg.
' -----------------------------------------------------------------
Dim OSVI As OSVERSIONINFO
Dim ff As Integer
 SetEnvironmentVariable VariableName, VariableValue
 OSVI.dwOSVersionInfoSize = Len(OSVI)
 GetVersionEx OSVI
 If OSVI.dwPlatformId VER\_PLATFORM\_WIN32\_NT Then
 On Error Resume Next
 ff = FreeFile()
 Open "c:\autoexec.bat" For Append As #ff
 Print #ff, "SET " & VariableName & "=" & VariableValue
 Close #ff
 SetEnvironVar = (Err.Number = 0)
 Exit Function
 End If
 If Systemwide Then
 If RegWriteString(HKEY\_LOCAL\_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", VariableName, VariableValue) = False Then
 Exit Function
 End If
 Else
 If RegWriteString(HKEY\_CURRENT\_USER, "Environment", VariableName, VariableValue) = False Then
 Exit Function
 End If
 End If
 Change "Environment"
 SetEnvironVar = True
End Function

Private Function RegWriteString(ByVal ToplevelKey As REGISTRYKEYS, ByVal SubKey As String, ByVal ValueName As String, ByVal Value As String) As Boolean
Dim RetVal As Long
Dim hKey As Long
Dim lngDisposition As Long
 If Left$(SubKey, 1) = "\" And Len(SubKey) \> 1 Then SubKey = Mid$(SubKey, 2)
 RetVal = RegCreateKeyEx(ToplevelKey, SubKey, 0, vbNullString, REG\_OPTION\_NON\_VOLATILE, KEY\_CREATE\_SUB\_KEY Or KEY\_SET\_VALUE, 0, hKey, lngDisposition)
 If RetVal = ERROR\_SUCCESS Then
 RetVal = RegSetValueEx(hKey, ValueName, 0, REG\_SZ, ByVal Value, Len(Value))
 RegWriteString = (RetVal = ERROR\_SUCCESS)
 End If
 RegCloseKey hKey
End Function

Private Sub Change(Optional ByVal Area As String, Optional ByVal Timeout As Long = 5000&amp:wink:
Dim lResult As Long
 SendMessageTimeout HWND\_BROADCAST, WM\_SETTINGCHANGE, 0, ByVal Area, SMTO\_ABORTIFHUNG, Timeout, lResult
End Sub

Private Sub GetEnvironVar()
Dim i As Long
Dim strEnvironVars As String
 i = 1
 Do While LenB(Environ$(i)) \> 0
 strEnvironVars = strEnvironVars & Environ$(i) & vbNewLine
 i = i + 1
 Loop
 If LenB(strEnvironVars) \> 0 Then
 strEnvironVars = Left$(strEnvironVars, Len(strEnvironVars) - 2)
 End If
 MsgBox "Die folgenden Umgebungsvariablen sind definiert:" & vbNewLine & vbNewLine & strEnvironVars, vbInformation, "Definierte Umgebungsvariable"
End Sub

Private Sub Form\_Load()
 SetEnvironVar "TestEintrag", "Test"
End Sub

Was mir aber hierbei aufgefallen ist, ist folgendes.
Der wert wird gesetzt. Aber wenn ich mir alle Umgebungsvariablen anzeigen lasse, mittels dem geposteten Code ( GetEnvironVar) bekomme ich ihn nicht angezeigt. Rufe ich jedoch die DOS Console auf und Gebe dort Set ein, so sehe ich ihn!
Laut microsoft, ist das aber normal. Ich zitiere mal ein Stueckchen.

Zitat:
Allein durch einen Eintrag in der Registry würden diese Umgebungsvariablen erst nach einem Windows-Neustart ausgelesen und gesetzt werden.
Um zu erreichen, dass nach dieser Änderung gestartete Anwendungen dennoch die neuen Variablen berücksichtigen, wird die Nachricht WM_SETTINGCHANGE mithilfe der Funktion SendMessageTimeout an alle Hauptfenster auf dem Desktop gesendet.
Als symbolisches Fensterhandle aller Empfänger wird dafür HWND_BROADCAST eingesetzt.
Auf bereits gestartete Anwendungen hat die Änderung jedoch keine Einwirkung.

Gruß
Reinhard

MfG Alex

Hallo Alex,

ich hatte gestern meinen USb-Stick vergessen und kann es erst heute abspeichern.
Ausprobieren kann ich es frühestens am WE.

Bis dahin erstmal vorab vielen Dank für deine Mühen

Lieben Gruß
Reinhard

Hallo Alex,

ich habe jetzt beide Varianten (nachfolgend in Modul1 udd Modul2) durchprobiert.
Bei beiden ist das Resultat das Gleiche.
Werden die Umgebungsvariablen aus dem Dosbefehl Set ausgelesen („set > c:\kurz.txt“), so werden die frisch gesetzten Variablen angezeigt, also das Variablensetzen funktioniert.
Leider sind die neuen Variablen nicht sichtbar durch die "GetEnviron
" oder eine Schleife über die Environ(x)

Zaghafte Versuche mit RegFlushKey brachten mir nichts, ich bin aber auch nicht sicher in der API-Anwendung, dann noch dazu in der Registry :smile:

Codeumsetzung nach VBA (XL2000) ging problemlos.

Ich schaue demnächst nach Code für direkte Registryänderung, vielleicht ergibt sich ja da eine Lösung daß ich auf eine Umgebungsvariable mit Environ(x) zugreifen kann und nicht den Umweg über Set gehen muß.

Noch ein schönes Rest-WE und Danke
Gruß
Reinhard

Die Datei: http://www.hostarea.de/server-10/Oktober-055650ee42.xls

In Modul1:

Option Explicit
'
Declare Function RegFlushKey& Lib "advapi32.dll" (ByVal hKey As Long)
'
Private Declare Function SetEnvironmentVariable \_
Lib "kernel32" Alias "SetEnvironmentVariableA" ( \_
ByVal EnvironmentVariableName As String, \_
ByVal EnvironmentVariableValue As String \_
) As Long
'
Private Const FORMAT\_MESSAGE\_FROM\_SYSTEM As Long = &H1000&
Private Const FORMAT\_MESSAGE\_IGNORE\_INSERTS As Long = &H200&
Private Const FORMAT\_MESSAGE\_MAX\_WIDTH\_MASK As Long = &HFF&
Private Const LANG\_USER\_DEFAULT As Long = &H400&
Private Declare Function FormatMessage \_
 Lib "kernel32" Alias "FormatMessageA" ( \_
 ByVal dwFlags As Long, \_
 ByRef lpSource As Any, \_
 ByVal dwMessageId As Long, \_
 ByVal dwLanguageId As Long, \_
 ByVal lpBuffer As String, \_
 ByVal nSize As Long, \_
 ByRef Arguments As Long \_
 ) As Long
'
Public Function APIErrorDescription(ByVal ErrLastDllError As Long) As String
Dim sBuffer As String
Dim lBufferLen As Long
 sBuffer = Space$(1024)
 lBufferLen = FormatMessage(FORMAT\_MESSAGE\_FROM\_SYSTEM Or FORMAT\_MESSAGE\_MAX\_WIDTH\_MASK Or FORMAT\_MESSAGE\_IGNORE\_INSERTS, ByVal 0&, ErrLastDllError, LANG\_USER\_DEFAULT, sBuffer, Len(sBuffer), 0)
 If lBufferLen \> 0 Then
 APIErrorDescription = Left$(sBuffer, lBufferLen)
 Else
 APIErrorDescription = "Unbekannter Fehler: &H" & Hex$(ErrLastDllError)
 End If
End Function
'
Function SetEnviron(sName As String, Wert As String, Optional ShowError As Boolean = True) As Boolean
Dim x As Long
 x = SetEnvironmentVariable(sName, Wert)
 If x 0 Then
 'Rückgabewert=1 -\> erfolgreich
 SetEnviron = True
 Else
 'Rückgabewert=0 -\> Fehlgeschlagen
 If ShowError Then MsgBox APIErrorDescription(Err.LastDllError)
 SetEnviron = False
 End If
End Function
'
Sub GetEnviron()
Dim i As Long
Dim strEnvironVars As String
 i = 1
 Do While LenB(Environ$(i)) \> 0
 strEnvironVars = strEnvironVars & Environ$(i) & vbNewLine
 Cells(i, 1) = Environ$(i)

 i = i + 1
 Loop
 If LenB(strEnvironVars) \> 0 Then
 strEnvironVars = Left$(strEnvironVars, Len(strEnvironVars) - 2)
 End If

 MsgBox "Die folgenden Umgebungsvariablen sind definiert:" & vbNewLine & vbNewLine & \_
 strEnvironVars, \_
 vbInformation, \_
 "Definierte Umgebungsvariable"
End Sub
'
Sub SetListe()
Dim Mache, zei, Satz
Close
Open "c:\kurz.bat" For Output As #1
Print #1, "set \> c:\kurz.txt"
Close
Mache = Shell("c:\kurz.bat")
Close
Open "c:\kurz.txt" For Input As #1
While Not EOF(1)
 zei = zei + 1
 Input #1, Satz
 Cells(zei, 2) = Satz
Wend
Close
End Sub
'
Sub EnvironListe()
Dim zei
While Len(Environ(zei + 1)) \> 0
 zei = zei + 1
 Cells(zei, 3) = Environ(zei)
Wend
End Sub
'
Sub Test()
Dim hh As Long
 SetEnviron "Peter", "Alex"
 'hh = RegFlushKey(1) 'passiert nichts
 'hh = RegFlushKey("HKEY\_CURRENT\_USER") 'Fehler
 GetEnviron ' zeigt nur die ersten 23 Einträge an
SetListe
EnvironListe
End Sub

in Modul2:

Option Explicit
'
Private Const WM\_WININICHANGE As Long = &H1A&
Private Const WM\_SETTINGCHANGE As Long = WM\_WININICHANGE
Private Const SMTO\_ABORTIFHUNG As Long = &H2&
Private Const HWND\_BROADCAST As Long = &HFFFF&
Private Const KEY\_CREATE\_SUB\_KEY As Long = &H4&
Private Const KEY\_SET\_VALUE As Long = &H2&
Private Const REG\_SZ As Long = &H1&
Private Const REG\_OPTION\_NON\_VOLATILE As Long = &H0&
Private Const ERROR\_SUCCESS As Long = &H0&
Private Const VER\_PLATFORM\_WIN32\_NT As Long = &H2&
'
Private Enum REGISTRYKEYS
 HKEY\_CLASSES\_ROOT = &H80000000
 HKEY\_CURRENT\_USER = &H80000001
 HKEY\_LOCAL\_MACHINE = &H80000002
 HKEY\_USERS = &H80000003
 HKEY\_PERFORMANCE\_DATA = &H80000004
 HKEY\_CURRENT\_CONFIG = &H80000005
 HKEY\_DYN\_DATA = &H80000006
End Enum
'
Private Declare Function SetEnvironmentVariable \_
 Lib "kernel32" Alias "SetEnvironmentVariableA" ( \_
 ByVal EnvironmentVariableName As String, \_
 ByVal EnvironmentVariableValue As String \_
 ) As Long
'
Private Type OSVERSIONINFO
 dwOSVersionInfoSize As Long
 dwMajorVersion As Long
 dwMinorVersion As Long
 dwBuildNumber As Long
 dwPlatformId As Long
 szCSDVersion As String \* 128
End Type
'
Private Declare Function GetVersionEx \_
 Lib "kernel32" Alias "GetVersionExA" ( \_
 ByRef VersionInformation As OSVERSIONINFO \_
 ) As Long
'
Private Declare Function RegCreateKeyEx \_
 Lib "advapi32.dll" Alias "RegCreateKeyExA" ( \_
 ByVal hKey As Long, \_
 ByVal SubKey As String, \_
 ByVal Reserved As Long, \_
 ByVal Class As String, \_
 ByVal Options As Long, \_
 ByVal DesiredAccess As Long, \_
 ByVal SecurityAttributes As Long, \_
 ByRef hKeyResult As Long, \_
 ByRef Disposition As Long \_
 ) As Long
'
Private Declare Function RegSetValueEx \_
 Lib "advapi32.dll" Alias "RegSetValueExA" ( \_
 ByVal hKey As Long, \_
 ByVal ValueName As String, \_
 ByVal Reserved As Long, \_
 ByVal TypeOfValue As Long, \_
 ByRef Value As Any, \_
 ByVal SizeOfValue As Long \_
 ) As Long
'
Private Declare Function RegCloseKey \_
 Lib "advapi32.dll" ( \_
 ByVal hKey As Long \_
 ) As Long
'
Private Declare Function SendMessageTimeout \_
 Lib "user32" Alias "SendMessageTimeoutA" ( \_
 ByVal hWnd As Long, \_
 ByVal Message As Long, \_
 ByVal wParam As Long, \_
 ByRef lParam As Any, \_
 ByVal Flags As Long, \_
 ByVal Timeout As Long, \_
 ByRef Result As Long \_
 ) As Long
'
Public Function SetEnvironVar(ByVal VariableName As String, \_
ByVal VariableValue As String, Optional ByVal Systemwide As Boolean = False) As Boolean
' VariableName: Name der neuen Umgebungsvariablen.
' VariableValue: Wert der neuen Umgebungsvariablen.
' Systemwide: Legt fest, ob eine Benutzer-Umgebungsvariable oder
' (nur WinNT) eine System-Umgebungsvariable erzeugt werden soll.
' TRUE: Es wird eine System-Umgebungsvariable erzeugt
' (hinreichende Rechte vorausgesetzt).
' FALSE: Es wird eine Benutzer-Umgebungsvariable erzeugt.
' Dieser Parameter hat unter Windows 9x/Me keine Wirkung.
' Rückgabewert: TRUE bei Erfolg, FALSE bei Misserfolg.
'
'-----------------------------------------------------------------
Dim OSVI As OSVERSIONINFO
Dim ff As Integer
 SetEnvironmentVariable VariableName, VariableValue
 OSVI.dwOSVersionInfoSize = Len(OSVI)
 GetVersionEx OSVI
 If OSVI.dwPlatformId VER\_PLATFORM\_WIN32\_NT Then
 On Error Resume Next
 ff = FreeFile()
 Open "c:\autoexec.bat" For Append As #ff
 Print #ff, "SET " & VariableName & "=" & VariableValue
 Close #ff
 SetEnvironVar = (Err.Number = 0)
 Exit Function
 End If
 If Systemwide Then
 If RegWriteString(HKEY\_LOCAL\_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", VariableName, VariableValue) = False Then
 Exit Function
 End If
 Else
 If RegWriteString(HKEY\_CURRENT\_USER, "Environment", VariableName, VariableValue) = False Then
 Exit Function
 End If
 End If
 Change "Environment"
 SetEnvironVar = True
End Function
'
Private Function RegWriteString(ByVal ToplevelKey As REGISTRYKEYS, ByVal SubKey As String, ByVal ValueName As String, ByVal Value As String) As Boolean
Dim RetVal As Long
Dim hKey As Long
Dim lngDisposition As Long
 If Left$(SubKey, 1) = "\" And Len(SubKey) \> 1 Then SubKey = Mid$(SubKey, 2)
 RetVal = RegCreateKeyEx(ToplevelKey, SubKey, 0, vbNullString, REG\_OPTION\_NON\_VOLATILE, KEY\_CREATE\_SUB\_KEY Or KEY\_SET\_VALUE, 0, hKey, lngDisposition)
 If RetVal = ERROR\_SUCCESS Then
 RetVal = RegSetValueEx(hKey, ValueName, 0, REG\_SZ, ByVal Value, Len(Value))
 RegWriteString = (RetVal = ERROR\_SUCCESS)
 End If
 RegCloseKey hKey
End Function
'
Private Sub Change(Optional ByVal Area As String, Optional ByVal Timeout As Long = 5000&amp:wink:
Dim lResult As Long
 SendMessageTimeout HWND\_BROADCAST, WM\_SETTINGCHANGE, 0, ByVal Area, SMTO\_ABORTIFHUNG, Timeout, lResult
End Sub
'
Private Sub GetEnvironVar()
Dim i As Long
Dim strEnvironVars As String
 i = 1
 Do While LenB(Environ$(i)) \> 0
 strEnvironVars = strEnvironVars & Environ$(i) & vbNewLine
 i = i + 1
 Loop
 If LenB(strEnvironVars) \> 0 Then
 strEnvironVars = Left$(strEnvironVars, Len(strEnvironVars) - 2)
 End If
 MsgBox "Die folgenden Umgebungsvariablen sind definiert:" & vbNewLine & vbNewLine & strEnvironVars, vbInformation, "Definierte Umgebungsvariable"
End Sub
'
Private Sub Form\_Load()
SetEnvironVar "TestEintrag", "Test"
GetEnviron ' zeigt nur die ersten 23 Einträge an
SetListe
EnvironListe
End Sub

Hallo Reinhard,

das hat mir nun keine Ruhe gelassen :s
Ich habe aber eine Idee, wie man zur Lösung kommt!

Wenn du dein Makro startest, dann liest du mittels Environ die Variable aus! Erhaelst du sie dann kannst du mit ihr weiter arbeiten. Sie steht ja dann in der Registry drinnen!
Erhaelst du sie nicht, was beim ersten Start normal ist, so setzt du sie! Also den Wert in die Registry schreiben! Natuerlich ist nun der Wert nicht bekannt! Als Notlösung tust du sie für den Prozess setzen und auslesen. Somit ist sie bekannt!

Wie du die Variable in die Registry schreibst, das weisst du. Wie du sie dann mittels Envoron bekommst, das weisst du auch! Wie du sie für den Prozess setzen tust und auslesen tust, poste ich dir gleich :smile:
Ich habe es bei mir probiert und es hat geklappt :smile:

Option Explicit

Private Declare Function GetEnvironmentVariable Lib \_
 "kernel32.dll" Alias "GetEnvironmentVariableA" (ByVal \_
 lpName As String, ByVal lpBuffer As String, ByVal \_
 nSize As Long) As Long

Private Declare Function SetEnvironmentVariable Lib \_
 "kernel32.dll" Alias "SetEnvironmentVariableA" (ByVal \_
 lpName As String, ByVal lpValue As String) As Long

Private Sub SetVariable(sName as String, Wert as String)
 Call SetEnvironmentVariable(sName,Wert)
End Sub

Private Function GetVariable(sName as String) as String
Dim Buffer As String
Dim l As Long
l = 256
Buffer = String$(l, Chr$(0))
l = GetEnvironmentVariable(sName, Buffer, l)
If l 0 Then
GetVariable = Left(Buffer, l)
Else
GetVariable=""
End If
End Sub

MfG Alex

Hallo Alex,
was du als „hat mir keine Ruhe gelassen“ bezeichnest, geht mir genauso. Kann doch gar nicht sein daß ich im laufenden Betrieb keine Umgebungsvariablen verändern kann.
Die dienen ja dazu von anderen Programmen ausgewertet zu werden.
Wie das Leben halt so spielt, per Zufall kam das da:

http://www.wer-weiss-was.de/cgi-bin/forum/showarticl…

Eben erst gesehen, wenn es durch Reinstellung einer Batch in diesen Ordner mein Problem löst, so ist das okay.
(Problem ist/war, aufgrund einer bestimmten Umgebungsvariablen etwas zu tun)

Nur, wie ich mit Excle-Vba eine Umgebungsvariable zur Laufzeit ändere und mit Environ auslese ist dadurch nicht gelöst.

Aber, lassen wir es gut sein, danke für deine Mühen
Gruß
Reinhard

Hallo Alex, Interessierte,

eine Batch in dem angegebenen Ordner brachte nichts, wird nicht ausgeführt.

Gruß
Reinhard