Jeśli zmodyfikuję lub dodam zmienną środowiskową, muszę ponownie uruchomić wiersz polecenia. Czy istnieje polecenie, które można wykonać, aby zrobić to bez ponownego uruchamiania CMD?
windows
cmd
environment-variables
Eric Schoonover
źródło
źródło
Odpowiedzi:
Możesz przechwycić systemowe zmienne środowiskowe za pomocą skryptu VBS, ale potrzebujesz skryptu nietoperza, aby faktycznie zmienić bieżące zmienne środowiskowe, więc jest to rozwiązanie łączone.
Utwórz plik o nazwie
resetvars.vbs
zawierającej ten kod i zapisz go na ścieżce:utwórz inną nazwę pliku resetvars.bat zawierającą ten kod, tę samą lokalizację:
Jeśli chcesz odświeżyć zmienne środowiskowe, po prostu uruchom
resetvars.bat
Apologetyka :
Dwa główne problemy, jakie wpadłem na to rozwiązanie, to:
za. Nie mogłem znaleźć prostego sposobu na eksport zmiennych środowiskowych ze skryptu vbs z powrotem do wiersza poleceń i
b. zmienna środowiskowa PATH jest konkatenacją użytkownika i systemowych zmiennych PATH.
Nie jestem pewien, jaka jest ogólna reguła dla sprzecznych zmiennych między użytkownikiem a systemem, dlatego zdecydowałem się na zastąpienie systemu przez użytkownika, z wyjątkiem zmiennej PATH, która jest obsługiwana konkretnie.
Używam dziwnego mechanizmu VBS + nietoperz + tymczasowy nietoperz, aby obejść problem eksportowania zmiennych z VBS.
Uwaga : ten skrypt nie usuwa zmiennych.
Można to prawdopodobnie poprawić.
DODANY
Jeśli chcesz wyeksportować środowisko z jednego okna cmd do drugiego, użyj tego skryptu (nazwijmy go
exportvars.vbs
):Uruchom
exportvars.vbs
w oknie chcesz wyeksportować z , a następnie przejść do okna, które chcesz wyeksportować do i wpisz:źródło
Oto, czego używa Chocolatey.
https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd
źródło
RefreshEnv
aby zaktualizować zmienne środowiskowe do bieżącej sesji.Powershell
? Wydaje się, że działa tylkocmd.exe
dla mnie.W systemie Windows 7/8/10 możesz zainstalować Chocolatey, który ma skrypt dla tego wbudowanego.
Po zainstalowaniu Chocolatey po prostu wpisz
refreshenv
.źródło
Z założenia nie ma wbudowanego mechanizmu dla systemu Windows do propagowania dodawania / zmiany / usuwania zmiennej środowiskowej do już uruchomionego cmd.exe, z innego cmd.exe lub z „Mój komputer -> Właściwości -> Ustawienia zaawansowane -> Zmienne środowiska".
Jeśli zmodyfikujesz lub dodasz nową zmienną środowiskową poza zakresem istniejącego otwartego wiersza polecenia, musisz albo zrestartować wiersz polecenia, albo ręcznie dodać za pomocą SET w istniejącym wierszu polecenia.
Te ostatnie Zaakceptowanych odpowiedź przedstawia częściowy obejść poprzez ręczne odświeżanie wszystkie zmienne środowiskowe w skrypcie. Skrypt obsługuje przypadek użycia globalnej zmiany zmiennych środowiskowych w „Mój komputer ... Zmienne środowiskowe”, ale jeśli zmienna środowiskowa zostanie zmieniona w jednym cmd.exe, skrypt nie propaguje jej do innego działającego cmd.exe.
źródło
Natknąłem się na tę odpowiedź, zanim w końcu znalazłem łatwiejsze rozwiązanie.
Po prostu uruchom ponownie
explorer.exe
w Menedżerze zadań.Nie testowałem, ale może być konieczne ponowne otwarcie wiersza polecenia.
Podziękowania dla Timo Huovinena tutaj: Węzeł nie został rozpoznany, chociaż został pomyślnie zainstalowany (jeśli to pomogło, proszę podać informację o komentarzu tego człowieka).
źródło
cmd
okno jako Administrator. Użyj poleceniataskkill /f /im explorer.exe && explorer.exe
. To zabije proces explorer.exe i uruchom go ponownie.Działa to w systemie Windows 7:
SET PATH=%PATH%;C:\CmdShortcuts
przetestowane przez wpisanie echa% PATH% i zadziałało, w porządku. ustaw także, jeśli otworzysz nowe cmd, nie ma już potrzeby tych nieznośnych restartów :)
źródło
setx
ponieważ dziedziczy bieżące środowisko, które może mieć zmienione zmienne, a nie to, czego chcę na stałe. Wykonanie tego w ten sposób pozwala mi uniknąć ponownego uruchamiania konsoli w celu użycia zmiennych, unikając jednocześnie problemu braku ich globalnej dostępności w przyszłości.Użyj „setx” i uruchom ponownie polecenie cmd
Dla tego zadania istnieje narzędzie wiersza polecenia o nazwie „ setx ”. Służy do odczytu i zapisu zmiennych env. Zmienne są zachowywane po zamknięciu okna poleceń.
„Tworzy lub modyfikuje zmienne środowiskowe w środowisku użytkownika lub systemu, bez konieczności programowania lub pisania skryptów. Komenda setx pobiera również wartości kluczy rejestru i zapisuje je w plikach tekstowych”.
Uwaga: zmienne utworzone lub zmodyfikowane przez to narzędzie będą dostępne w przyszłych oknach poleceń, ale nie w bieżącym oknie poleceń CMD.exe. Musisz więc zrestartować.
Jeśli
setx
brakuje:Lub zmodyfikuj rejestr
MSDN mówi:
źródło
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\VARIABLE
obecne środowisko użytkownika:HKEY_CURRENT_USER\Environment\VARIABLE
%PATH%
czas,setx
możesz go skrócić do 1024 bajtów! I tak po prostu jego wieczór zniknąłWywołanie tej funkcji zadziałało dla mnie:
źródło
Najlepszą metodą, jaką wymyśliłem, było wykonanie zapytania do rejestru. Oto mój przykład.
W moim przykładzie wykonałem instalację przy użyciu pliku Batch, który dodał nowe zmienne środowiskowe. Musiałem to zrobić, gdy tylko instalacja się zakończy, ale nie byłem w stanie odrodzić nowego procesu z tymi nowymi zmiennymi. Przetestowałem odradzanie innego okna eksploratora i zadzwoniłem z powrotem do cmd.exe i działało to, ale w Vista i Windows 7 Explorer działa tylko jako jedna instancja i normalnie jako osoba zalogowana. Nie udałoby się to z automatyzacją, ponieważ potrzebuję moich uprawnień administratora, aby rób rzeczy niezależnie od uruchamiania z systemu lokalnego lub jako administrator w pudełku. Ograniczeniem jest to, że nie obsługuje rzeczy takich jak ścieżka, działało to tylko na prostych zmiennych środowiskowych. To pozwoliło mi użyć partii do przejścia do katalogu (ze spacjami) i skopiowania plików do uruchomienia .exes itp. To zostało napisane dzisiaj z zasobów maja na stackoverflow.com
Połączenia z oryginalną partią do nowej partii:
testenvget.cmd SDROOT (lub jakakolwiek zmienna)
Jest też inna metoda, którą wymyśliłem z różnych różnych pomysłów. Patrz poniżej. To w zasadzie pobierze najnowszą zmienną ścieżki z rejestru, jednak spowoduje to szereg problemów, ponieważ zapytanie rejestru poda zmienne samo w sobie, co oznacza, że wszędzie tam, gdzie jest zmienna, to nie zadziała, więc aby zwalczyć ten problem I w zasadzie podwajaj ścieżkę. Bardzo paskudny. Bardziej udoskonaloną metodą byłoby: Ustaw ścieżkę =% ścieżki%; C: \ Program Files \ Software .... \
Bez względu na to jest nowy plik wsadowy, należy zachować ostrożność.
źródło
Najłatwiejszym sposobem dodania zmiennej do ścieżki bez ponownego uruchamiania dla bieżącej sesji jest otwarcie wiersza polecenia i wpisanie:
i naciśnij enter .
aby sprawdzić, czy zmienna została załadowana, wpisz
i naciśnij enter. Jednak zmienna będzie tylko częścią ścieżki, dopóki nie uruchomisz się ponownie.
źródło
Można to zrobić, zastępując tabelę środowiska w ramach określonego procesu.
Jako dowód koncepcji napisałem tę przykładową aplikację, która właśnie edytowała jedną (znaną) zmienną środowiskową w procesie cmd.exe:
Przykładowe dane wyjściowe:
Notatki
Takie podejście byłoby również ograniczone do ograniczeń bezpieczeństwa. Jeśli cel jest uruchamiany na wyższym poziomie lub na wyższym koncie (takim jak SYSTEM), nie mielibyśmy uprawnień do edycji jego pamięci.
Jeśli chcesz to zrobić w aplikacji 32-bitowej, powyższe przesunięcia kodowane na stałe zmieniłyby się odpowiednio na 0x10 i 0x48. Te przesunięcia można znaleźć, usuwając struktury _PEB i _RTL_USER_PROCESS_PARAMETERS w debuggerze (np. W WinDbg
dt _PEB
idt _RTL_USER_PROCESS_PARAMETERS
)Aby zmienić proof-of-concept na to, czego potrzebuje OP, wystarczy wyliczyć bieżące zmienne systemowe i środowiskowe użytkownika (takie jak udokumentowane odpowiedzią @ tsadok) i zapisać całą tabelę środowiska w pamięci procesu docelowego.
Edycja: Rozmiar bloku środowiska jest również przechowywany w strukturze _RTL_USER_PROCESS_PARAMETERS, ale pamięć jest przydzielana na stercie procesu. Zatem z procesu zewnętrznego nie mielibyśmy możliwości zmiany jego rozmiaru i powiększenia. Bawiłem się przy użyciu VirtualAllocEx do przydzielenia dodatkowej pamięci w procesie docelowym do przechowywania środowiska, i byłem w stanie ustawić i odczytać zupełnie nową tabelę. Niestety każda próba modyfikacji środowiska z normalnych środków ulegnie awarii i zostanie spalona, ponieważ adres nie będzie już wskazywał na stos (spowoduje awarię w RtlSizeHeap).
źródło
Zmienne środowiskowe są przechowywane w HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet \ Control \ Session Manager \ Environment.
Wiele przydatnych zmiennych środowisk, takich jak Ścieżka, jest przechowywanych jako REG_SZ. Istnieje kilka sposobów dostępu do rejestru, w tym REGEDIT:
REGEDIT /E <filename> "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"
Wyjście zaczyna się od magicznych liczb. Aby go wyszukać za pomocą polecenia find, należy wpisać i przekierować:
type <filename> | findstr -c:\"Path\"
Jeśli więc chcesz odświeżyć zmienną ścieżki w bieżącej sesji poleceń za pomocą właściwości systemowych, następujący skrypt wsadowy działa dobrze:
RefreshPath.cmd:
źródło
Spróbuj otworzyć nowy wiersz polecenia jako administrator. Działa to dla mnie w systemie Windows 10. (Wiem, że to stara odpowiedź, ale musiałem się nią podzielić, ponieważ pisanie skryptu VBS tylko w tym celu jest absurdalne).
źródło
Ponowne uruchomienie eksploratora zrobiło to dla mnie, ale tylko dla nowych terminali cmd.
Terminal, dla którego ustawiłem ścieżkę, mógł już zobaczyć nową zmienną Path (w Windows 7).
źródło
Mylące może być to, że istnieje kilka miejsc, od których można zacząć cmd. W moim przypadku uruchomiłem cmd z Eksploratora Windows i zmienne środowiskowe nie uległy zmianie, a podczas uruchamiania cmd z „uruchom” (klawisz Windows + r) zmienne środowiskowe zostały zmienione .
W moim przypadku musiałem po prostu zabić proces eksploratora Windows z menedżera zadań, a następnie ponownie uruchomić go z menedżera zadań .
Kiedy to zrobiłem, miałem dostęp do nowej zmiennej środowiskowej z cmd, która została spawnowana z Eksploratora Windows.
źródło
Używam następującego kodu w skryptach wsadowych:
Używając SET po SETX można bezpośrednio używać zmiennej „lokalnej” bez ponownego uruchamiania okna poleceń. A przy następnym uruchomieniu zostanie użyta zmienna środowiskowa.
źródło
Podobało mi się podejście czekoladowe, jak podano w odpowiedzi anonimowego tchórza, ponieważ jest to podejście czysto wsadowe. Pozostawia jednak plik tymczasowy i niektóre zmienne tymczasowe. Zrobiłem dla siebie czystszą wersję.
Zrób plik
refreshEnv.bat
gdzieś na swoimPATH
. Odśwież środowisko konsoli, wykonującrefreshEnv
.źródło
Jeśli dotyczy tylko jednego (lub kilku) konkretnych zmiennych, które chcesz zmienić, myślę, że najłatwiejszym sposobem jest obejście tego problemu : po prostu ustaw w swoim środowisku ORAZ w bieżącej sesji konsoli
Mam ten prosty skrypt wsadowy, aby zmienić mój Maven z Java7 na Java8 (które są oba w środowisku zmiennym). Folder wsadowy znajduje się w mojej zmiennej PATH, więc zawsze mogę wywołać „ j8 ” oraz w konsoli i w środowisku mój JAVA_HOME var ulega zmianie:
j8.bat:
Do tej pory uważam, że to działa najlepiej i najłatwiej. Prawdopodobnie chcesz, aby było to w jednym poleceniu, ale po prostu nie ma go w systemie Windows ...
źródło
Rozwiązanie, z którego korzystam od kilku lat:
Edycja: Woops, oto zaktualizowana wersja.
źródło
Nie ma prostej drogi, jak powiedział Kev. W większości przypadków łatwiej jest odrodzić kolejne pole CMD. Co bardziej denerwujące, uruchomione programy również nie są świadome zmian (chociaż IIRC może mieć komunikat do wysłania, aby powiadomić o takiej zmianie).
Gorzej: w starszych wersjach systemu Windows trzeba było się wylogować, a następnie zalogować ponownie, aby uwzględnić zmiany ...
źródło
Używam tego skryptu Powershell, aby dodać do zmiennej PATH . Uważam, że przy niewielkiej korekcie może również działać w twoim przypadku.
źródło
Dziękujemy za opublikowanie tego pytania, które jest dość interesujące, nawet w 2019 r. (Rzeczywiście, odnowienie powłoki cmd nie jest łatwe, ponieważ jest to pojedyncze wystąpienie, jak wspomniano powyżej), ponieważ odnawianie zmiennych środowiskowych w systemie Windows pozwala na wykonanie wielu zadań automatyzacji bez konieczność ręcznego ponownego uruchomienia wiersza polecenia.
Na przykład używamy tego, aby umożliwić wdrażanie i konfigurowanie oprogramowania na dużej liczbie komputerów, które regularnie instalujemy. I muszę przyznać, że ponowne uruchomienie wiersza poleceń podczas wdrażania naszego oprogramowania byłoby bardzo niepraktyczne i wymagałoby od nas znalezienia obejść, które niekoniecznie są przyjemne. Przejdźmy do naszego problemu. Postępujemy w następujący sposób.
1 - Mamy skrypt wsadowy, który z kolei wywołuje taki skrypt PowerShell
[plik: zadanie.cmd] .
cmd
> powershell.exe -executionpolicy unrestricted -File C:\path_here\refresh.ps1
2 - Następnie skrypt refresh.ps1 odnawia zmienne środowiskowe za pomocą kluczy rejestru (GetValueNames () itp.). Następnie, w tym samym skrypcie PowerShell, musimy wywołać nowe dostępne zmienne środowiskowe. Na przykład, w typowym przypadku, jeśli przed chwilą zainstalowaliśmy nodeJS z cmd przy użyciu cichych poleceń, po wywołaniu funkcji możemy bezpośrednio wywołać npm w celu zainstalowania, w tej samej sesji, określonych pakietów, takich jak poniżej.
[plik: refresh.ps1]
Po zakończeniu skryptu PowerScript skrypt cmd wykonuje inne zadania. Teraz należy pamiętać, że po zakończeniu zadania cmd nadal nie ma dostępu do nowych zmiennych środowiskowych, nawet jeśli skrypt PowerShell zaktualizował je w swojej sesji. Dlatego wykonujemy wszystkie potrzebne zadania w skrypcie PowerShell, który może wywoływać te same polecenia co cmd.
źródło
Edycja: działa to tylko wtedy, gdy zmiany środowiska, które wprowadzasz, są wynikiem uruchomienia pliku wsadowego.
Jeśli plik wsadowy zaczyna się od,
SETLOCAL
to zawsze wyjdzie z powrotem do oryginalnego środowiska przy wyjściu, nawet jeśli zapomnisz zadzwonićENDLOCAL
przed wyjściem z partii lub jeśli niespodziewanie zostanie przerwana.Prawie każdy plik wsadowy, który piszę, zaczyna się
SETLOCAL
od, ponieważ w większości przypadków nie chcę, aby skutki uboczne zmian środowiska pozostały. W przypadkach, w których chcę, aby pewne zmiany zmiennych środowiskowych były propagowane poza plikiem wsadowym, moje ostatnieENDLOCAL
wygląda następująco:źródło
Aby rozwiązać ten problem, zmieniłem zmienną środowiskową za pomocą ZARÓWNO setx i set, a następnie zrestartowałem wszystkie instancje explorer.exe. W ten sposób każdy później uruchomiony proces będzie miał nową zmienną środowiskową.
Mój skrypt wsadowy, aby to zrobić:
Problem z tym podejściem polega na tym, że wszystkie otwarte okna eksploratora zostaną zamknięte, co jest prawdopodobnie złym pomysłem - ale zobacz post Kev, aby dowiedzieć się, dlaczego jest to konieczne
źródło