Wiersz polecenia, aby usunąć zmienną środowiskową z konfiguracji na poziomie systemu operacyjnego

182

Windows ma setxpolecenie:

Description:
    Creates or modifies environment variables in the user or system
    environment.

Możesz więc ustawić taką zmienną:

setx FOOBAR 1

Możesz wyczyścić wartość w ten sposób:

setx FOOBAR ""

Jednak zmienna nie jest usuwana. Pozostaje w rejestrze:

foobar

Jak więc właściwie usunąć zmienną?

Peter Mortensen
źródło
3
setx po prostu ustawia zmienną. Po prostu czyścisz to tą linią.
Fox Wilson
1
zobacz także stackoverflow.com/questions/1472722/…
Brian Burns
Ponieważ zajęło mi to sporo pracy, zobacz również superuser.com/q/297947/46834, aby uzyskać informacje o opcjach innych niż wiersz poleceń.
Gary

Odpowiedzi:

217

Aby usunąć zmienną z bieżącego środowiska ( nie na stałe):

set FOOBAR=

Aby trwale usunąć zmienną ze środowiska użytkownika (które jest domyślnym miejscem setxumieszcza ją):

REG delete HKCU\Environment /F /V FOOBAR

Jeśli zmienna jest ustawiona w środowisku systemowym (np. Jeśli ustawiłeś ją pierwotnie za pomocą setx /M), jako administrator uruchom:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR

Uwaga: REGpowyższe polecenia nie wpłyną na żadne istniejące procesy (i niektóre nowe procesy, które są rozwidlone z istniejących procesów), więc jeśli ważne jest, aby zmiana zaczęła obowiązywać natychmiast, najłatwiej i najpewniejszą rzeczą do zrobienia jest wylogowanie się i ponowne zalogowanie lub uruchom ponownie. Jeśli to nie jest opcja lub chcesz zagłębić się w szczegóły, niektóre inne odpowiedzi tutaj zawierają kilka świetnych sugestii, które mogą pasować do twojego przypadku użycia.

CupawnTae
źródło
1
Wydaje się, że to rozwiązanie nie działa - albo nie rozumiem czegoś podstawowego. Tak setx JUNK Hello. Otwórz nowy cmd. Wpisz echo %JUNK%i pobierz Hello. Następnie robię REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V JUNKi potwierdzam, że wartość zniknęła z rejestru. Otwieram nowe cmd i piszę echo %JUNK%i nadal otrzymuję Hello. Przeszukiwanie rejestru nie wykazało obecności „JUNK”. Nie mów mi, że potrzebujesz restartu!
caasjj
Dziękuję za odpowiedź. Otwieram nowe okno poleceń z menu Start. Wypróbowałem obie wersje polecenia. W rzeczywistości, kiedy po raz pierwszy userwpisuję polecenie środowiska, kończy się to pomyślnie. Następnie, kiedy ponownie wpisuję polecenie, które otrzymuję The system was unable to find the specified registry or key value. Ponadto globalne wyszukiwanie JUNKw rejestrze regeditnic nie daje . Mimo to, kiedy otwieram nowe okno poleceń (przez Start / akcesoria lub cmd.exe w Run) i wpisuję echo %JUNK%, wartość nadal tam jest!
caasjj
1
Ach! Jak myślisz, co jest racjonalne? Zawsze unikam administratora - wychowanie UNIX / BSD / Linux. Wielkie dzięki za niesamowitą pracowitość. +1
caasjj
4
może to tylko semantyka, ale usunięcie (z rejestru) działa natychmiast. Środowisko nie jest ponownie inicjowane z rejestru do czasu ponownego zalogowania. Możesz połączyć 2 polecenia, aby usunąć go z bieżącego środowiska (co spowoduje usunięcie go z SETlisty dla następnej powłoki cmd), a następnie usunąć go z rejestru, np .:SETX FOOBAR "" & REG delete HKCU\Environment /F /V FOOBAR
Luke
1
Powodem, dla którego wydaje się, że środowisko nie jest aktualizowane bez ponownego uruchomienia, jest to, że program explorer.exe nie wie, że został zaktualizowany. Zobacz moją odpowiedź, aby uzyskać pełne wyjaśnienie i rozwiązanie.
Jamie
72

Aby usunąć zmienną z bieżącej sesji poleceń bez usuwania jej na stałe, użyj zwykłego wbudowanego setpolecenia - po prostu nie wstaw nic po znaku równości:

set FOOBAR=

Aby potwierdzić, uruchom setbez argumentów i sprawdź bieżące środowisko. Zmiennej powinno całkowicie brakować na liście.

Uwaga : spowoduje to usunięcie zmiennej tylko z bieżącego środowiska - nie utrwali zmiany w rejestrze. Po uruchomieniu nowego procesu polecenia zmienna wróci.

Brian Kelly
źródło
77
To zdecydowanie NIE jest odpowiedź i uważam za niepokojące, że jest tak wiele pozytywnych głosów. Dotyczy to tylko bieżącej sesji poleceń. Podkręć nowe okno poleceń, a var powraca.
joescii
6
@joescii Uważasz, że to zaskakujące? To odpowiadało na pytanie w tytule pytania. Więc oczywiście tytuł pytania musiał być bardziej szczegółowy.
oberlies
10
@oberlies Nie zgadzam się, że odpowiada na pytanie w tytule, ponieważ NIE działa to na poziomie systemu operacyjnego, a tylko w bieżącym oknie poleceń. Po drugie, twój punkt widzenia sugeruje, że część dotycząca szczegółów pytania jest nieistotna.
joescii
3
@oberlies niestety wydaje się, że edycja nie przyniosła efektu - wciąż pojawiają się głosy poparcia. Myślę, że ludzie uważają to za przydatne, nawet jeśli nie odpowiada na rzeczywiste pytanie, w takim przypadku może zasługuje na pochwały (prawda?). Przynajmniej nie jest oznaczony jako zaakceptowany, co byłoby mylące.
CupawnTae
3
Mam skomentować, dlaczego przegłosowałem. Oczywiście, ponieważ działa to tylko w bieżącej sesji.
Ian Grainger
22

Omówiono to sporo, ale brakuje kluczowej informacji. Mam nadzieję, że pomogę wyjaśnić, jak to działa i przynieść ulgę zmęczonym podróżnikom. :-)

Usuń z bieżącego procesu

Oczywiście wszyscy wiedzą, że robisz to po prostu, aby usunąć zmienną środowiskową z bieżącego procesu:

set FOO=

Trwałe usuwanie

Istnieją dwa zestawy zmiennych środowiskowych, ogólnosystemowe i użytkownika.

Usuń zmienną środowiska użytkownika:

reg delete "HKCU\Environment" /v FOO /f

Usuń ogólnosystemową zmienną środowiskową:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOO

Zastosuj wartość bez ponownego uruchamiania

Oto magiczne informacje, których brakuje! Zastanawiasz się, dlaczego po wykonaniu tej czynności, kiedy uruchamiasz nowe okno poleceń, zmienna środowiskowa nadal tam jest. Powodem jest to, że program explorer.exe nie zaktualizował swojego środowiska. Gdy jeden proces uruchamia inny, nowy proces dziedziczy środowisko po procesie, który go uruchomił.

Istnieją dwa sposoby rozwiązania tego problemu bez ponownego uruchamiania. Najbardziej brutalnym sposobem jest zabicie procesu explorer.exe i ponowne jego uruchomienie. Możesz to zrobić w Menedżerze zadań . Nie polecam jednak tej metody.

Innym sposobem jest poinformowanie programu explorer.exe, że środowisko się zmieniło i że powinien je ponownie przeczytać. Odbywa się to poprzez rozgłaszanie wiadomości Windows (WM_SETTINGCHANGE). Można to osiągnąć za pomocą prostego skryptu PowerShell. Możesz łatwo napisać taki, aby to zrobić, ale znalazłem go w ustawieniach okna aktualizacji po zmianach skryptowych :

if (-not ("win32.nativemethods" -as [type])) {
    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

[win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE,[uintptr]::Zero, "Environment", 2, 5000, [ref]$result);

Podsumowanie

Aby więc usunąć zmienną środowiskową użytkownika o nazwie „FOO” i odzwierciedlić zmianę w procesach uruchamianych później, wykonaj następujące czynności.

  1. Zapisz skrypt PowerShell w pliku (nazwiemy go updateenv.ps1).
  2. Zrób to z wiersza poleceń: reg delete „HKCU \ Environment” / v FOO / f
  3. Uruchom updateenv.ps1.
  4. Zamknij i ponownie otwórz wiersz polecenia, a zobaczysz, że zmienna środowiskowa nie jest już zdefiniowana.

Uwaga, prawdopodobnie będziesz musiał zaktualizować ustawienia PowerShell, aby umożliwić uruchomienie tego skryptu, ale zostawię to jako ćwiczenie Google-fu.

Jamie
źródło
Czy jest jakiś szczególny powód, dla którego nie zalecamy zabijania i ponownego uruchamiania eksploratora? Ciągle to robię.
Prometheus
Cóż, najpierw przychodzą mi do głowy dwie. Po pierwsze, procesy wymuszające zabijanie mogą powodować wycieki pamięci. Tak, procesy mają być piaskownicami, ale nawet Menedżer zadań systemu Windows ostrzega, aby nie robić tego lekko. Innym bardziej osobistym powodem jest moje ZOK. Po zabiciu i ponownym uruchomieniu Eksploratora wszystkie ikony na pasku zadań, w tym duplikaty po kliknięciu jednego, zostaną uporządkowane. Lubię, gdy moje ikony pozostają w kolejności, w której otworzyłem rzeczy.
Jamie
1
Łał. Magiczne polecenie, którego szukałem, działa jak source .bashrc(lub jego kuzyni) w systemie Windows. To trafia na początek wiersza „odnieś się do tego”.
bballdave025
18

Z PowerShell można skorzystać z [System.Environment]::SetEnvironmentVariable()metody .NET :

  • Aby usunąć zmienną środowiskową użytkownika o nazwie FOO:

    [Environment]::SetEnvironmentVariable('FOO', $null, 'User')
    

Zauważ, że $nulljest to używane do lepszego zasygnalizowania zamiaru usunięcia zmiennej, chociaż technicznie jest to to samo, co przekazanie ''w tym przypadku.

  • Aby usunąć systemową zmienną środowiskową (na poziomie komputera) o nazwie FOO- wymaga podniesienia uprawnień ( musi być uruchomiona jako administrator):

    [Environment]::SetEnvironmentVariable('FOO', $null, 'Machine')
    

Oprócz szybszego wykonywania, zaletą reg.exemetody opartej na metodzie jest to, że inne aplikacje są powiadamiane o zmianie za pośrednictwem WM_SETTINGCHANGEkomunikatu (chociaż nie wszystkie aplikacje nasłuchują tego komunikatu).

mklement0
źródło
2
To najlepsza odpowiedź.
James
1
Ta metoda pozwala uniknąć ponownego uruchamiania. Cóż za eleganckie rozwiązanie!
jyao
13

Zgadzam się z CupawnTae .

SET nie jest użyteczny w przypadku zmian w środowisku głównym.

FYI: zmienne systemowe są w HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (znacznie dłużej niż użytkownika).

Dlatego pełne polecenie dla zmiennej systemowej o nazwie FOOBAR to:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR

(Zwróć uwagę na cudzysłowy wymagane do obsługi spacji).

Szkoda setx polecenie nie obsługuje składni usuwania. :(

PS: Używaj odpowiedzialnie - jeśli zabijesz zmienną ścieżki, nie obwiniaj mnie!

DougWare
źródło
@CMCDragonkai, który jest wyraźnie wspomniany w pierwotnym pytaniu - nie usuwa wpisu rejestru, po prostu go pustuje. Właściwe pytanie brzmi, jak usunąć go z rejestru
CupawnTae
1
Dodam tylko, że może być konieczne ponowne uruchomienie / odświeżenie cmd, zanim to zacznie obowiązywać.
jiggunjer
@jiggunjer, jak odświeżyć?
Pacerier
@Pacerier po prostu otwórz nowy terminal.
jiggunjer
11

Polecenie w odpowiedzi DougWare nie zadziałało, ale to:

reg delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v FOOBAR /f

Skrót HKLMmoże służyć do HKEY_LOCAL_MACHINE.

user4297498
źródło
1
Ponadto zmienne środowiskowe użytkownika znajdują się w „HKCU \ Environment”
tzrlk
1
@Tzrlk, Jaki jest powód niezgodności? Dlaczego nie ma go w HKLM \ Environment?
Pacerier
@Pacerier: Nie mam pojęcia, dlaczego umieścili je w tak całkowicie oddzielnych lokalizacjach, ale jeśli chcesz się upewnić, że usunąłeś / obie zmienne systemowe lub / i zmienne użytkownika, warto wiedzieć, że są one w zupełnie innych miejscach miejsc.
tzrlk
2
@Tzrlk, Musi być znowu jakiś przykręcony projekt po stronie Windows.
Pacerier
4

Usuń bez ponownego uruchamiania

Na pytanie OP rzeczywiście udzielono obszernej odpowiedzi, w tym jak uniknąć ponownego uruchamiania za pomocą PowerShell, VBScript lub jak to nazwać.

Jeśli jednak musisz trzymać się tylko poleceń cmd i nie masz luksusu możliwości wywoływania PowerShell lub VBScript, możesz zastosować następujące podejście:

rem remove from current cmd instance
  SET FOOBAR=
rem remove from the registry if it's a user variable
  REG delete HKCU\Environment /F /V FOOBAR
rem remove from the registry if it's a system variable
  REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR
rem tell Explorer.exe to reload the environment from the registry
  SETX DUMMY ""
rem remove the dummy
  REG delete HKCU\Environment /F /V DUMMY

Więc magia polega na tym, że używając "setx" do przypisania czegoś do zmiennej, której nie potrzebujesz (w moim przykładzie DUMMY), zmuszasz Explorer.exe do ponownego odczytania zmiennych z rejestru, bez konieczności korzystania z PowerShell. Następnie wyczyścisz ten manekin i nawet jeśli pozostanie on w środowisku Explorera jeszcze przez chwilę, prawdopodobnie nikomu nie zaszkodzi.

Lub jeśli po usunięciu zmiennych musisz ustawić nowe, nie potrzebujesz nawet żadnego atrapy. Samo użycie SETX do ustawienia nowych zmiennych automatycznie wyczyści te, które właśnie usunąłeś z wszelkich nowych zadań cmd, które mogą się rozpocząć.

Informacje ogólne: Właśnie z powodzeniem zastosowałem to podejście, aby zastąpić zestaw zmiennych użytkownika zmiennymi systemowymi o tej samej nazwie na wszystkich komputerach w mojej pracy, modyfikując istniejący skrypt cmd. Jest zbyt wiele komputerów, aby zrobić to ręcznie, ani skopiowanie do nich wszystkich dodatkowych programów PowerShell lub VBScript nie było praktyczne. Powodem, dla którego pilnie potrzebowałem zastąpić użytkownika zmiennymi systemowymi, było to, że zmienne użytkownika są synchronizowane w profilach mobilnych (nie myślałem o tym), więc wiele komputerów używających tego samego logowania do systemu Windows, ale wymagających różnych wartości, zostało pomieszanych.

Ronny D'Hoore
źródło
3
setx FOOBAR ""

po prostu powoduje, że wartość FOOBAR jest łańcuchem pustym. (Chociaż pokazuje się z rozszerzeniemset poleceniem z „”, więc może to być ciąg znaków w cudzysłowie).

Użyłem:

set FOOBAR=

a następnie FOOBAR nie był już wymieniony w komendzie set. (Wylogowanie nie było wymagane.)

Windows 7 32-bitowy, używając wiersza poleceń, użyłem bez administratora. (Nie cmd ani Windows+ R, które mogą być inne).

Przy okazji, nie widziałem zmiennej, którą utworzyłem w żadnym miejscu rejestru po jej utworzeniu. używam RegEdit nie jako administrator.

PReinie
źródło
1

Możesz także utworzyć mały skrypt VBScript :

Set env = CreateObject("WScript.Shell").Environment("System")
If env(WScript.Arguments(0)) <> vbNullString Then env.Remove WScript.Arguments(0)

Następnie nazwij to jak %windir%\System32\cscript.exe //Nologo "script_name.vbs" FOOBAR .

Wadą jest to, że potrzebujesz dodatkowego skryptu, ale nie wymaga on ponownego uruchomienia.

Wernfried Domscheit
źródło