Gibt es einen Befehl Umgebungsvariablen aus der Eingabeaufforderung in Windows zu aktualisieren?

StackOverflow https://stackoverflow.com/questions/171588

Frage

Wenn ich ändern oder eine Umgebungsvariable hinzufügen, ich habe die Eingabeaufforderung neu zu starten. Gibt es einen Befehl, den ich das tun würde, dies ohne Neustart CMD ausführen kann?

War es hilfreich?

Lösung

Sie können die Systemumgebungsvariablen mit einem vbs Skript erfassen, aber Sie müssen ein Skript bittet, um tatsächlich die aktuellen Umgebungsvariablen zu ändern, so ist dies eine kombinierte Lösung.

Erstellen Sie eine Datei mit dem Namen resetvars.vbs diesen Code enthält, und es auf dem Pfad speichern:

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("System")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
path = oEnv("PATH")

set oEnv=oShell.Environment("User")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next

path = path & ";" & oEnv("PATH")
oFile.WriteLine("SET PATH=" & path)
oFile.Close

erstellen Sie einen anderen Dateinamen resetvars.bat diesen Code enthält, gleichen Ort:

@echo off
%~dp0resetvars.vbs
call "%TEMP%\resetvars.bat"

Wenn Sie die Umgebungsvariablen aktualisieren möchten, führen Sie einfach resetvars.bat


Apologetics :

Die beiden wichtigsten Probleme, die ich hatte mit dieser Lösung kommen wurden

ein. Ich kann nicht eine einfache Art und Weise zu exportieren Umgebungsvariablen von einem vbs Skript zurück zur Eingabeaufforderung finden, und

b. die Umgebungsvariable PATH ist eine Verkettung von dem Benutzer und dem System PATH-Variablen.

Ich bin mir nicht sicher, was die allgemeine Regel für die widerstreitenden Variablen zwischen Benutzer und System, so dass ich gewählt Benutzern Übersteuerungssytem zu machen, außer in den PATH-Variablen, die speziell behandelt wird.

Ich benutze die seltsamen vbs + Schläger + temporären Fledermaus Mechanismus, um das Problem der exportierenden Variablen aus vbs zu arbeiten.

Hinweis . Dieses Skript Variablen nicht gelöscht

Dies kann wahrscheinlich verbessert werden.

ADDED

Wenn Sie die Umgebung von einem cmd Fenster zu einem anderen exportieren müssen, dieses Skript verwenden (nennen wir es exportvars.vbs):

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("Process")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
oFile.Close

Ausführen exportvars.vbs im Fenster Sie exportieren möchten, wechseln Sie dann auf das Fenster, das Sie exportieren möchten , und geben Sie:

"%TEMP%\resetvars.bat"

Andere Tipps

Hier ist, was Chocolatey verwendet.

https://github.com/ chocolatey / choco / Blob / Master / src / chocolatey.resources / Umleitungen / RefreshEnv.cmd

@echo off
::
:: RefreshEnv.cmd
::
:: Batch file to read environment variables from registry and
:: set session variables to these values.
::
:: With this batch file, there should be no need to reload command
:: environment every time you want environment changes to propagate

echo | set /p dummy="Reading environment variables from registry. Please wait... "

goto main

:: Set one environment variable from registry key
:SetFromReg
    "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL
    for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do (
        echo/set %~3=%%B
    )
    goto :EOF

:: Get a list of environment variables from registry
:GetRegEnv
    "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp"
    for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do (
        if /I not "%%~A"=="Path" (
            call :SetFromReg "%~1" "%%~A" "%%~A"
        )
    )
    goto :EOF

:main
    echo/@echo off >"%TEMP%\_env.cmd"

    :: Slowly generating final file
    call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd"
    call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd"

    :: Special handling for PATH - mix both User and System
    call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd"
    call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd"

    :: Caution: do not insert space-chars before >> redirection sign
    echo/set Path=%%Path_HKLM%%;%%Path_HKCU%% >> "%TEMP%\_env.cmd"

    :: Cleanup
    del /f /q "%TEMP%\_envset.tmp" 2>nul
    del /f /q "%TEMP%\_envget.tmp" 2>nul

    :: Set these variables
    call "%TEMP%\_env.cmd"

    echo | set /p dummy="Done"
    echo .

Mit dem Design gibt es keine Mechanismus gebaut für Windows eine Umgebungsvariable hinzufügen / ändern / entfernen zu einem bereits laufenden cmd.exe propagieren, entweder von einer anderen cmd.exe oder von „My Computer -> Eigenschaften -> Erweiterte Einstellungen -.> Umgebungsvariablen“

Wenn Sie ändern oder eine neue Umgebungsvariable hinzufügen, außerhalb des Geltungsbereichs eines bestehenden offenen Eingabeaufforderung müssen Sie entweder die Eingabeaufforderung starten, oder fügen Sie manuell SET in der bestehenden Eingabeaufforderung.

Die letzte akzeptierte Antwort zeigt eine Teil work-around durch manuelles Auffrischen alle die Umgebungsvariablen in einem Skript. Das Skript übernimmt den Anwendungsfall der Umgebung zu ändern Variablen global in „My Computer ... Umgebungsvariablen“, aber wenn eine Umgebungsvariable in einem cmd.exe geändert wird, das Skript wird es nicht zu einem anderen läuft cmd.exe propagieren.

Unter Windows 7/8/10 Sie können Chocolatey installieren, die ein Skript für diese eingebaut hat.

Nach Chocolatey installieren, geben Sie einfach "refreshenv" ohne Anführungszeichen.

Dies funktioniert auf Windows 7: SET PATH=%PATH%;C:\CmdShortcuts

getestet von echo% PATH% eingeben und es funktionierte, in Ordnung. auch einstellen, wenn Sie einen neuen cmd öffnen, keine Notwendigkeit für die lästigen Reboots mehr:)

Ich kam in dieser Antwort, bevor er schließlich eine einfachere Lösung zu finden.

Starten Sie einfach explorer.exe im Task-Manager.

habe ich nicht getestet, aber Sie müssen auch Sie Eingabeaufforderung wieder zu öffnen.

Kredit href="https://stackoverflow.com/users/175071/timo-huovinen"> Timo Huovinen hier: Knoten nicht, obwohl erfolgreich installiert anerkannt (wenn diese Ihnen geholfen, gehen Sie bitte dieses Mannes Kommentar Kredit geben).

Verwenden Sie "setx" und starten Sie cmd Aufforderung

Es ist ein Kommandozeilen-Tool namens „ setx " Für diese Arbeit. Es ist für Lesen und Schreiben env Variablen. Die Variablen bestehen bleiben, nachdem das Befehlsfenster geschlossen wurde.

It „Erstellt oder ändert Umgebungsvariablen in der Benutzer oder Systemumgebung, ohne dass Programmierung oder Scripting. Die setx Befehl auch die Werte der Registrierungsschlüssel abruft und schreibt sie in Textdateien.“

Hinweis: Variablen von diesem Tool erstellt oder geändert wird künftig Kommandofenster zur Verfügung, aber nicht im aktuellen CMD.exe Befehlsfenstern. Also, müssen Sie neu starten.

Wenn setx fehlt:


oder ändern Sie die Registrierung

MSDN sagt:

  

Um programmatisch hinzufügen oder Systemumgebungsvariablen ändern, hinzufügen   sie die    HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session   Manager \ Environment Registrierungsschlüssel übertragen dann ein WM_SETTINGCHANGE   Nachricht mit lParam auf den String " Umwelt ".

     

Dies ermöglicht Anwendungen, wie die Schale, die Updates zu holen.

Der Aufruf dieser Funktion hat für mich gearbeitet:

VOID Win32ForceSettingsChange()
{
    DWORD dwReturnValue;
    ::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
}

Die beste Methode, die ich herauskommen, war nur eine Registry-Abfrage zu tun. Hier ist mein Beispiel.

In meinem Beispiel habe ich ein mit einer Batch-Datei installieren, die neuen Umgebungsvariablen hinzugefügt. Ich musste Dinge mit diesem, sobald die Installation abgeschlossen war tun, aber nicht in der Lage war, ein neues Verfahren mit den neuen Variablen laichen. Getestet habe ich eine anderes Explorer-Fenster Laichen und zurück zu cmd.exe und das funktionierte aber auf Vista und Windows 7, Explorer läuft nur als einzelne Instanz und in der Regel als die Person angemeldet. Dies würde nicht mit Automatisierung genannt, da ich meinen Admin creds muß Dinge tun, unabhängig davon, auf dem Feld von lokalen System oder als Administrator ausgeführt wird. Die Beschränkung auf diese besteht darin, dass es nicht behandelt Dinge wie Weg, dies funktioniert nur auf einfache Umgebungsvariablen. Das erlaubte mir, eine Charge zu verwenden, um ein Verzeichnis zu verwinden (mit Leerzeichen) und kopieren Sie in Dateien ausgeführt .exes und etc. Dies wurde heute geschrieben von Mai Ressourcen auf stackoverflow.com

Batch Orginal Anrufe auf neue Batch:

testenvget.cmd SDROOT (oder was auch immer die Variablen)

@ECHO OFF
setlocal ENABLEEXTENSIONS
set keyname=HKLM\System\CurrentControlSet\Control\Session Manager\Environment
set value=%1
SET ERRKEY=0

REG QUERY "%KEYNAME%" /v "%VALUE%" 2>NUL| FIND /I "%VALUE%"
IF %ERRORLEVEL% EQU 0 (
ECHO The Registry Key Exists 
) ELSE (
SET ERRKEY=1
Echo The Registry Key Does not Exist
)

Echo %ERRKEY%
IF %ERRKEY% EQU 1 GOTO :ERROR

FOR /F "tokens=1-7" %%A IN ('REG QUERY "%KEYNAME%" /v "%VALUE%" 2^>NUL^| FIND /I "%VALUE%"') DO (
ECHO %%A
ECHO %%B
ECHO %%C
ECHO %%D
ECHO %%E
ECHO %%F
ECHO %%G
SET ValueName=%%A
SET ValueType=%%B
SET C1=%%C
SET C2=%%D
SET C3=%%E
SET C4=%%F
SET C5=%%G
)

SET VALUE1=%C1% %C2% %C3% %C4% %C5%
echo The Value of %VALUE% is %C1% %C2% %C3% %C4% %C5%
cd /d "%VALUE1%"
pause
REM **RUN Extra Commands here**
GOTO :EOF

:ERROR
Echo The the Enviroment Variable does not exist.
pause
GOTO :EOF

Auch gibt es eine andere Methode, die ich mit aus verschiedenen Ideen kam. Siehe unten. Diese im Grunde wird die neuesten Pfadvariablen aus der Registry jedoch erhalten, dies wird eine Reihe von Fragen beacuse der Registrierung Abfrage verursachen wird Variablen in mir selbst geben, bedeutet, dass überall dort ist eine Variable dies nicht funktionieren wird, so dieses Problem zu bekämpfen I im Grunde den Weg verdoppeln. Sehr böse. Je mehr perfered Methode zu tun wäre:     Set Path =% Path%; C: \ Program Files \ Software .... \

Unabhängig hier ist die neue Batch-Datei, bitte seien Sie vorsichtig.

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
set org=%PATH%
for /f "tokens=2*" %%A in ('REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path ^|FIND /I "Path"') DO (
SET path=%%B
)
SET PATH=%org%;%PATH%
set path

Es ist möglich, dies zu tun, indem Sie die Umwelt Tabelle innerhalb eines festgelegten Verfahrens zu überschreiben selbst.

Als proof of concept ich dieses Beispiel-App geschrieben, die nur einen einzigen (bekannten) Umgebungsvariable in einem cmd.exe Prozess bearbeitet:

typedef DWORD (__stdcall *NtQueryInformationProcessPtr)(HANDLE, DWORD, PVOID, ULONG, PULONG);

int __cdecl main(int argc, char* argv[])
{
    HMODULE hNtDll = GetModuleHandleA("ntdll.dll");
    NtQueryInformationProcessPtr NtQueryInformationProcess = (NtQueryInformationProcessPtr)GetProcAddress(hNtDll, "NtQueryInformationProcess");

    int processId = atoi(argv[1]);
    printf("Target PID: %u\n", processId);

    // open the process with read+write access
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, 0, processId);
    if(hProcess == NULL)
    {
        printf("Error opening process (%u)\n", GetLastError());
        return 0;
    }

    // find the location of the PEB
    PROCESS_BASIC_INFORMATION pbi = {0};
    NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
    if(status != 0)
    {
        printf("Error ProcessBasicInformation (0x%8X)\n", status);
    }
    printf("PEB: %p\n", pbi.PebBaseAddress);

    // find the process parameters
    char *processParamsOffset = (char*)pbi.PebBaseAddress + 0x20; // hard coded offset for x64 apps
    char *processParameters = NULL;
    if(ReadProcessMemory(hProcess, processParamsOffset, &processParameters, sizeof(processParameters), NULL))
    {
        printf("UserProcessParameters: %p\n", processParameters);
    }
    else
    {
        printf("Error ReadProcessMemory (%u)\n", GetLastError());
    }

    // find the address to the environment table
    char *environmentOffset = processParameters + 0x80; // hard coded offset for x64 apps
    char *environment = NULL;
    ReadProcessMemory(hProcess, environmentOffset, &environment, sizeof(environment), NULL);
    printf("environment: %p\n", environment);

    // copy the environment table into our own memory for scanning
    wchar_t *localEnvBlock = new wchar_t[64*1024];
    ReadProcessMemory(hProcess, environment, localEnvBlock, sizeof(wchar_t)*64*1024, NULL);

    // find the variable to edit
    wchar_t *found = NULL;
    wchar_t *varOffset = localEnvBlock;
    while(varOffset < localEnvBlock + 64*1024)
    {
        if(varOffset[0] == '\0')
        {
            // we reached the end
            break;
        }
        if(wcsncmp(varOffset, L"ENVTEST=", 8) == 0)
        {
            found = varOffset;
            break;
        }
        varOffset += wcslen(varOffset)+1;
    }

    // check to see if we found one
    if(found)
    {
        size_t offset = (found - localEnvBlock) * sizeof(wchar_t);
        printf("Offset: %Iu\n", offset);

        // write a new version (if the size of the value changes then we have to rewrite the entire block)
        if(!WriteProcessMemory(hProcess, environment + offset, L"ENVTEST=def", 12*sizeof(wchar_t), NULL))
        {
            printf("Error WriteProcessMemory (%u)\n", GetLastError());
        }
    }

    // cleanup
    delete[] localEnvBlock;
    CloseHandle(hProcess);

    return 0;
}

Beispiel für die Ausgabe:

>set ENVTEST=abc

>cppTest.exe 13796
Target PID: 13796
PEB: 000007FFFFFD3000
UserProcessParameters: 00000000004B2F30
environment: 000000000052E700
Offset: 1528

>set ENVTEST
ENVTEST=def

Notizen

Dieser Ansatz würde auch zu Sicherheitsbeschränkungen begrenzt werden. Wenn das Ziel bei höherer Erhebung oder ein höheres Konto (zB SYSTEM) ausgeführt wird, dann würden wir nicht berechtigt, seinen Speicher zu bearbeiten.

Wenn Sie wollen dies zu einer 32-Bit-Anwendung tun, die hart codierten Offsets zu 0x10 und 0x48 oben würden jeweils ändern. Diese Offsets können durch Dumping aus dem _PEB und _RTL_USER_PROCESS_PARAMETERS structs in einem Debugger (beispielsweise in WinDbg dt _PEB und dt _RTL_USER_PROCESS_PARAMETERS)

finden

, um die Proof-of-Concept zu ändern in ein, was der OP Bedarf, es wäre nur das aktuelle System- und Benutzerumgebungsvariablen auflisten (wie dokumentiert durch @ tsadok Antwort) und schreiben Sie die gesamte Umgebung Tabelle in den Zielprozess Speicher .

Edit: Die Größe des Umgebungsblocks auch in der _RTL_USER_PROCESS_PARAMETERS Struktur gespeichert ist, aber die Erinnerung an den Prozess Heap zugewiesen. Also von einem externen Prozess hätten wir es nicht die Möglichkeit haben, um die zu Größe und es größer zu machen. Ich spielte mit VirtualAllocEx mit zusätzlichem Speicher im Zielprozess für die Umwelt Lagerung und war in der Lage zu setzen und las eine völlig neue Tabelle zuzuordnen. Leider jeder Versuch, die Umgebung von normalen Mitteln zu ändern, wird als die Adresse nicht mehr Punkte abstürzen und brennen auf dem Heap (es wird in RtlSizeHeap abstürzen).

Umgebungsvariablen werden in HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet \ Control \ Session Manager \ Environment gehalten.

Viele der nützlichen env vars, wie Path, werden als REG_SZ gespeichert. Es gibt mehrere Möglichkeiten, um die Registrierung einschließlich REGEDIT zuzugreifen:

REGEDIT /E &lt;filename&gt; "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"

Die Ausgabe beginnt mit magischen Zahlen. So suchen sie mit dem Befehl find es muss eingegeben werden und umgeleitet: type <filename> | findstr -c:\"Path\"

Wenn Sie also nur mit dem Pfad-Variable in der aktuellen Befehlssitzung aktualisieren mögen, was in Systemeigenschaften die folgende Batch-Skript funktioniert:

RefreshPath.cmd:

    @echo off

    REM This solution requests elevation in order to read from the registry.

    if exist %temp%\env.reg del %temp%\env.reg /q /f

    REGEDIT /E %temp%\env.reg "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"

    if not exist %temp%\env.reg (
       echo "Unable to write registry to temp location"
       exit 1
       )

    SETLOCAL EnableDelayedExpansion

    for /f "tokens=1,2* delims==" %%i in ('type %temp%\env.reg ^| findstr -c:\"Path\"=') do (
       set upath=%%~j
       echo !upath:\\=\! >%temp%\newpath
       )

     ENDLOCAL

     for /f "tokens=*" %%i in (%temp%\newpath) do set path=%%i

Die verwirrende Sache könnte sein, dass es ein paar Orte sind von der cmd zu starten. In meinem Fall lief ich cmd aus dem Windows Explorer und Umwelt Variablen nicht ändern , während beim Start cmd aus dem "run" (Windows-Taste + r) die Umwelt Variablen wurden geändert .

In meinem Fall habe ich nur hatte töten den Windows Explorer-Prozess aus dem Task-Manager und starten Sie ihn neu wieder aus dem Task-Manager .

Nachdem ich das tat hatte ich Zugriff auf die neue Umgebungsvariable von einem cmd, die aus dem Windows Explorer hervorgebracht wurden.

Versuchen Sie, eine neue Eingabeaufforderung als Administrator zu öffnen. Dieser arbeitete für mich unter Windows 10. (Ich weiß, das ist eine alte Antwort, aber ich hatte das teilen, weil mit einem VBS-Skript zu schreiben, nur für diese ist absurd).

Der einfachste Weg, um eine Variable zu dem Pfad hinzugefügt werden, ohne für die aktuelle Sitzung Neustart ist die Eingabeaufforderung zu öffnen und geben Sie:

PATH=(VARIABLE);%path%

und drücken Sie eingeben .

überprüfen, ob Ihre Variable geladen, geben Sie

PATH

und drücken Sie eingeben . Allerdings wird die Variable nur ein Teil des Weges, bis Sie neu starten.

Ein Neustart Explorer tat dies für mich, aber nur für neues cmd-Terminals.

Das Terminal habe ich den Pfad bereits die neue Variable Pfad sehen konnte (in Windows 7).

taskkill /f /im explorer.exe && explorer.exe

Ich verwende den folgenden Code in meinen Batch-Skripten:

if not defined MY_ENV_VAR (
    setx MY_ENV_VAR "VALUE" > nul
    set MY_ENV_VAR=VALUE
)
echo %MY_ENV_VAR%

Durch die Verwendung von SET nach SETX ist es möglich, das "lokale" Variable direkt zu verwenden, ohne den Befehl Fenster neu zu starten. Und auf den nächsten Lauf wird die Umgebungsvariable verwendet werden.

nur explorer.exe neu starten >> getestet auf Win 8 X64

Ich mochte den Ansatz von chocolatey gefolgt, wie in anonymen Feigling Antwort geschrieben, da es sich um eine reine Batch-Ansatz. Allerdings lässt es eine temporäre Datei und einige temporäre Variablen herumliegen. Ich habe eine saubere Version für mich.

Erstellen Sie eine Datei refreshEnv.bat irgendwo auf Ihrem PATH. Aktualisieren Sie Ihre Konsole Umgebung von refreshEnv ausgeführt wird.

@ECHO OFF
REM Source found on https://github.com/DieterDePaepe/windows-scripts
REM Please share any improvements made!

REM Code inspired by http://stackoverflow.com/questions/171588/is-there-a-command-to-refresh-environment-variables-from-the-command-prompt-in-w

IF [%1]==[/?] GOTO :help
IF [%1]==[/help] GOTO :help
IF [%1]==[--help] GOTO :help
IF [%1]==[] GOTO :main

ECHO Unknown command: %1
EXIT /b 1 

:help
ECHO Refresh the environment variables in the console.
ECHO.
ECHO   refreshEnv       Refresh all environment variables.
ECHO   refreshEnv /?        Display this help.
GOTO :EOF

:main
REM Because the environment variables may refer to other variables, we need a 2-step approach.
REM One option is to use delayed variable evaluation, but this forces use of SETLOCAL and
REM may pose problems for files with an '!' in the name.
REM The option used here is to create a temporary batch file that will define all the variables.

REM Check to make sure we don't overwrite an actual file.
IF EXIST %TEMP%\__refreshEnvironment.bat (
  ECHO Environment refresh failed!
  ECHO.
  ECHO This script uses a temporary file "%TEMP%\__refreshEnvironment.bat", which already exists. The script was aborted in order to prevent accidental data loss. Delete this file to enable this script.
  EXIT /b 1
)

REM Read the system environment variables from the registry.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"`) DO (
  REM /I -> ignore casing, since PATH may also be called Path
  IF /I NOT [%%I]==[PATH] (
    ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat
  )
)

REM Read the user environment variables from the registry.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment`) DO (
  REM /I -> ignore casing, since PATH may also be called Path
  IF /I NOT [%%I]==[PATH] (
    ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat
  )
)

REM PATH is a special variable: it is automatically merged based on the values in the
REM system and user variables.
REM Read the PATH variable from the system and user environment variables.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH`) DO (
  ECHO SET PATH=%%K>>%TEMP%\__refreshEnvironment.bat
)
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment /v PATH`) DO (
  ECHO SET PATH=%%PATH%%;%%K>>%TEMP%\__refreshEnvironment.bat
)

REM Load the variable definitions from our temporary file.
CALL %TEMP%\__refreshEnvironment.bat

REM Clean up after ourselves.
DEL /Q %TEMP%\__refreshEnvironment.bat

ECHO Environment successfully refreshed.

Wenn es sich nur eine (oder wenige) spezifische Vars Sie ändern wollen, glaube ich, der einfachste Weg, eine ist Abhilfe : nur in Ihrer Umgebung und in der aktuellen Konsolensitzung festgelegt in

  • Set wird die var in der aktuellen Sitzung setzen
  • SETX die var in der Umwelt setzen, aber nicht in der aktuellen Sitzung

Ich habe diesen einfachen Batch-Skript zu meinem Maven von Java7 zu Java8 ändern (die beide env. VARs) Der Batch-Ordner ist in meinem PATH var so dass ich immer ‚nennen kann J8 ‘und in meiner Konsole und in der Umgebung mein JAVA_HOME var wird geändert:

j8.bat:

@echo off
set JAVA_HOME=%JAVA_HOME_8%
setx JAVA_HOME "%JAVA_HOME_8%"

Bis ich dies jetzt finden Arbeit am besten und am einfachsten. Wahrscheinlich wollen Sie diese in einem Befehl sein, aber es ist einfach nicht da in Windows ...

Installieren Sie zuerst choco:

  • Wenn mit cmd @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

  • , wenn mithilfe von Powershell Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Dann können Sie refreshenv laufen. Es funktioniert sowohl auf cmd und Powershell.

Es gibt keinen geraden Weg, wie Kev sagte. In den meisten Fällen ist es einfacher, eine andere CMD-Box, um zu laichen. Mehr annoyingly, sind laufende Programme von Änderungen nicht bewusst entweder (obwohl IIRC könnte es eine Broadcast-Nachricht von einer solchen Änderung benachrichtigt zu sehen sein).

Es war schlimmer: in älteren Versionen von Windows, mußte man dann abmelden anmelden, um die Änderungen Konto zurück zu nehmen ...

Ich benutze diesen Powershell-Skript auf den PATH Variable hinzuzufügen. Mit einer wenig Anpassung kann es in Ihrem Fall auch glaube ich.

#REQUIRES -Version 3.0

if (-not ("win32.nativemethods" -as [type])) {
    # import sendmessagetimeout from win32
    add-type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
   IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
   uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
"@
}

$HWND_BROADCAST = [intptr]0xffff;
$WM_SETTINGCHANGE = 0x1a;
$result = [uintptr]::zero

function global:ADD-PATH
{
    [Cmdletbinding()]
    param ( 
        [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)] 
        [string] $Folder
    )

    # See if a folder variable has been supplied.
    if (!$Folder -or $Folder -eq "" -or $Folder -eq $null) { 
        throw 'No Folder Supplied. $ENV:PATH Unchanged'
    }

    # Get the current search path from the environment keys in the registry.
    $oldPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

    # See if the new Folder is already in the path.
    if ($oldPath | Select-String -SimpleMatch $Folder){ 
        return 'Folder already within $ENV:PATH' 
    }

    # Set the New Path and add the ; in front
    $newPath=$oldPath+';'+$Folder
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop

    # Show our results back to the world
    return 'This is the new PATH content: '+$newPath

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result)
}

function global:REMOVE-PATH {
    [Cmdletbinding()]
    param ( 
        [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)]
        [String] $Folder
    )

    # See if a folder variable has been supplied.
    if (!$Folder -or $Folder -eq "" -or $Folder -eq $NULL) { 
        throw 'No Folder Supplied. $ENV:PATH Unchanged'
    }

    # add a leading ";" if missing
    if ($Folder[0] -ne ";") {
        $Folder = ";" + $Folder;
    }

    # Get the Current Search Path from the environment keys in the registry
    $newPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

    # Find the value to remove, replace it with $NULL. If it's not found, nothing will change and you get a message.
    if ($newPath -match [regex]::Escape($Folder)) { 
        $newPath=$newPath -replace [regex]::Escape($Folder),$NULL 
    } else { 
        return "The folder you mentioned does not exist in the PATH environment" 
    }

    # Update the Environment Path
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop

    # Show what we just did
    return 'This is the new PATH content: '+$newPath

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result)
}


# Use ADD-PATH or REMOVE-PATH accordingly.

#Anything to Add?

#Anything to Remove?

REMOVE-PATH "%_installpath_bin%"

Vielen Dank, dass Sie diese Frage für die Buchung, die sehr interessant ist, auch im Jahr 2019 (In der Tat, es ist nicht leicht, die Shell cmd zu erneuern, da es eine einzige Instanz ist, wie oben erwähnt), da Umwelt zu erneuern Variablen in Fenstern ermöglicht viele zu erreichen Automatisierungsaufgaben ohne manuell über die Befehlszeile neu starten zu müssen.

Zum Beispiel verwenden wir diese Software zu ermöglichen, bereitgestellt und auf einer großen Anzahl von Maschinen konfiguriert werden, die wir regelmäßig neu installieren. Und ich muss zugeben, dass bei der Bereitstellung unserer Software über die Befehlszeile neu starten zu müssen wäre sehr unpraktisch und würde uns erfordern Abhilfen zu finden, die nicht unbedingt angenehm sind. Kommen wir zu unserem Problem. Wir gehen Sie wie folgt vor.

1 - Wir haben einen Batch-Skript, das einen Powershell-Skript, wie dies wiederum ruft

[file: task.cmd] .

cmd > powershell.exe -executionpolicy unrestricted -File C:\path_here\refresh.ps1

2 - Danach erneuert der refresh.ps1 Skript, um die Umgebungsvariablen Registrierungsschlüssel (GetValueNames (), etc.). Dann wird in dem gleichen Powershell-Skript, müssen wir nur zur Verfügung, die neuen Umgebungsvariablen nennen. Zum Beispiel in einem typischen Fall, wenn wir NodeJS vor mit cmd stillen Befehlen nur installiert haben, nachdem die Funktion aufgerufen wurde, können wir direkt npm rufen zu installieren, in der gleichen Sitzung, insbesondere Pakete wie folgt.

[file: refresh.ps1]

function Update-Environment {
    $locations = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session  Manager\Environment',
                 'HKCU:\Environment'
    $locations | ForEach-Object {
        $k = Get-Item $_
        $k.GetValueNames() | ForEach-Object {
            $name  = $_
            $value = $k.GetValue($_)

            if ($userLocation -and $name -ieq 'PATH') {
                $env:Path += ";$value"
            } else {

                Set-Item -Path Env:\$name -Value $value
            }
        }
        $userLocation = $true
    }
}
Update-Environment
#Here we can use newly added environment variables like for example npm install.. 
npm install -g create-react-app serve

Sobald der Powershell-Skript beendet ist, geht die cmd-Skript mit anderen Aufgaben zu. Jetzt, im Geist eine Sache zu behalten ist, dass, nachdem die Aufgabe beendet ist, cmd noch keinen Zugriff auf die neuen Umgebungsvariablen hat, auch wenn der Powershell-Skript die in einer eigenen Sitzung aktualisiert hat. Das ist, warum wir alle benötigten Aufgaben in der Powershell-Skript zu tun, die die gleichen Befehle wie cmd natürlich aufrufen können.

Nein, ich glaube nicht, so ... Sie sie manuell obwohl einstellen. So können Sie sie in einer Batch-Datei oder etwas setzen.

könnte wahrscheinlich einen Dienstprogramm / script machen (wenn jemand nicht schon hat), dass die Registrierung abfragt und setzt die aktuelle Umgebung das gleiche sein

Edit:. Dies funktioniert nur, wenn die Umgebung Sie tun sind als Folge der laufenden eine Batch-Datei ändert

Wenn eine Batch-Datei beginnt mit SETLOCAL dann wird es immer wieder in der ursprünglichen Umgebung an der Ausfahrt entwirren, auch wenn Sie vergessen ENDLOCAL, bevor die Batch-Exits zu rufen, oder wenn es bricht unerwartet.

Fast jede Batch-Datei Ich schreibe beginnt mit SETLOCAL da in den meisten Fällen möchte ich nicht die Nebenwirkungen von Umweltveränderungen bleiben. In Fällen, in denen ich Variable bestimmten Umgebungsänderungen wollen außerhalb der Batchdatei dann mein letzter ENDLOCAL sieht wie folgt propagieren:

ENDLOCAL & (
  SET RESULT1=%RESULT1%
  SET RESULT2=%RESULT2%
)

Um dies zu lösen, habe ich die Umgebungsvariable geändert BEID setx und Satz verwendet, und neu gestartet dann alle Instanzen explorer.exe. Auf diese Weise jeden Prozess anschließend die neue Umgebungsvariable wird gestartet.

Mein Batch-Skript, dies zu tun:

setx /M ENVVAR "NEWVALUE"
set ENVVAR="NEWVALUE"

taskkill /f /IM explorer.exe
start explorer.exe >nul
exit

Das Problem bei diesem Ansatz ist, dass alle Explorer-Fenster, die derzeit geschlossen werden geöffnet, das ist wahrscheinlich eine schlechte Idee - aber den Beitrag von Kev sehen zu lernen, warum dies notwendig ist

Sie können auch tun Sie es einfach manuell über

  

Zum Anzeigen oder Umgebungsvariablen ändern: Mit der rechten Maustaste auf Arbeitsplatz, und   dann auf Eigenschaften. Klicken Sie auf die Registerkarte Erweitert. klicken Sie auf Umgebung   Variablen. Klicken Sie auf eine der folgenden Möglichkeiten, für einen Benutzer oder eine   Systemvariable: Neu Klicken Sie auf einen neuen Variablennamen und Wert hinzuzufügen. Klicken   eine vorhandene Variable, und dann auf Bearbeiten seinen Namen oder Wert zu ändern.   Klicken Sie auf eine vorhandene Variable, und klicken Sie dann auf Löschen, um sie zu entfernen.    http://support.microsoft.com/kb/310519

Windows XP Umgebungsvariablen

%ALLUSERSPROFILE% (%PROGRAMDATA%)   C:\Documents and Settings\All Users
%APPDATA%   C:\Documents and Settings\{username}\Application Data
%COMPUTERNAME%  {computername}
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  \Documents and Settings\{username}
%LOCALAPPDATA%  Not available
%LOGONSERVER%   \\{domain_logon_server}
%PATH%  C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths}
%PATHEXT%   .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.WSF;.WSH
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PROMPT%    Code for current command prompt format. Code is usually $P$G
%SystemDrive%   C:
%SystemRoot%    The Windows directory, usually C:\Windows, formerly C:\WINNT
%TEMP% and %TMP%    C:\Documents and Settings\{username}\Local Settings\Temp
%USERDOMAIN%    {userdomain}
%USERNAME%  {username}
%USERPROFILE%   C:\Documents and Settings\{username}
%WINDIR%    C:\Windows
%PUBLIC%    
%PROGRAMDATA%   Only available in Windows Vista and newer versions
%PSModulePath%  

Windows 7 Umgebungsvariablen

%ALLUSERSPROFILE% (%PROGRAMDATA%)   C:\ProgramData
%APPDATA%   C:\Users\{username}\AppData\Roaming
%COMPUTERNAME%  {computername}
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  \Users\{username}
%LOCALAPPDATA%  C:\Users\{username}\AppData\Local
%LOGONSERVER%   \\{domain_logon_server}
%PATH%  C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths}
%PATHEXT%   .com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PROMPT%    Code for current command prompt format. Code is usually $P$G
%SystemDrive%   C:
%SystemRoot%    C:\Windows
%TEMP% and %TMP%    C:\Users\{username}\AppData\Local\Temp
%USERDOMAIN%    {userdomain}
%USERNAME%  {username}
%USERPROFILE%   C:\Users\{username}
%WINDIR%    C:\Windows
%PUBLIC%    C:\Users\Public
%PROGRAMDATA%   C:\ProgramData
%PSModulePath%  %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules\

http://www.binbert.com/blog/2010/09/default-environment-variable-values-of-windows-7-xp/

hoffe, das hilft.

Geben Sie einfach "# -r" (ohne Anführungszeichen # mit Option -r) in Ihrem Terminal. Und sie sind einstellen Pfade auf Standard:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top