Ustaw trwałą zmienną środowiskową z cmd.exe

123

Muszę ustawić zmienneśrodowiskowe na różnych komputerach z systemem Windows, ale nie chcę, aby przeszkadzało mi to ich ręczne zmienianie, przechodząc do ekranu właściwości "Mój komputer"

Chcę to zrobić z wiersza poleceń za pomocą pliku wsadowego. O ile rozumiem, użycie set zmieni tylko zmienną dla procesów, które wywołam w oknie poleceń.

Chcę to zdecydowanie ustawić, więc później, podczas uruchamiania nowego procesu, użyje nowych ustawień, które ustawiłem. Czy jest na to sposób z poziomu wiersza poleceń?

Arthur
źródło
Jaki jest sens ustawiania ich z wiersza poleceń, jeśli mają być trwałe? Nie będziesz musiał tego robić ponownie.
d-live
12
Tak, ale muszę to zrobić na kilku komputerach, więc uruchomienie skryptu zaoszczędzi mi trochę czasu.
Arthur
2
Ok, w takim przypadku możesz ustawić env na jednym komputerze i wykonać eksport wpisów opisanych poniżej i mieć plik .reg, jeśli SETX nie jest dostępny.
d-live
To właśnie zrobiłem. Dzięki.
Arthur
1
RE: „Jaki jest sens ustawiania ich z poziomu wiersza poleceń…” Tam, gdzie pracuję, istnieje ciągły wymóg posiadania wielu trwałych zmiennych środowiskowych na różne wartości w celu testowania / rozwijania różnych wersji oprogramowania. Licencjonowanie oznacza, że ​​nie można tego zrobić w żaden inny sposób (np. Uruchomienie maszyny wirtualnej), więc naszym jedynym rozwiązaniem jest użycie SETX w skrypcie wsadowym. Używanie .reg jest mniej dobre, ponieważ trudniej jest udokumentować / zobaczyć dokładnie, co się dzieje
Tony Eastwood

Odpowiedzi:

189

Użyj polecenia SETX (zwróć uwagę na przyrostek „x”), aby ustawić zmienne, które pozostają niezmienione po zamknięciu okna cmd.

Na przykład, aby ustawić zmienną env „foo” z wartością „bar”:

setx foo bar

Chociaż warto przeczytać `` notatki '', które są wyświetlane, gdy drukujesz użycie ( setx /?), w szczególności:

2) W systemie lokalnym 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.

3) W systemie zdalnym zmienne utworzone lub zmodyfikowane przez to narzędzie będą dostępne podczas następnej sesji logowania.

W programie PowerShell polecenie [Environment] :: SetEnvironmentVariable .

Vik David
źródło
Wygląda na to, że SETX jest dostępny tylko w systemie Windows XP SP2
Arthur
2
U mnie działało na Windows 7. Jakiej wersji systemu Windows używasz?
Vik David
@jules: W takim razie możesz go pobrać z zestawu zasobów.
Joey
46
Uważaj na SETX, skraca zmienną długość do 1024 znaków ... bardzo niebezpieczne podczas manipulowania% path%.
Etienne Desgagné
2
z Power Shell możesz po prostu [Environment]::SetEnvironmentVariable('PATH', "Whatever you need it to be", "Machine")zobaczyć msdn.microsoft.com/en-us/library/96xafkes(v=vs.110).aspx
Gradient
21

Dokumentacja MSDN dotycząca zmiennych środowiskowych zawiera instrukcje, co należy zrobić:

Aby programowo dodać lub zmodyfikować zmienne środowiskowe systemu, dodaj je do klucza rejestru HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment , a następnie rozgłaszaj komunikat WM_SETTINGCHANGE z lParam ustawionym na ciąg znaków „Environment”. Dzięki temu aplikacje, takie jak powłoka, mogą pobierać aktualizacje.

Aby to zrobić, będziesz oczywiście potrzebować uprawnień administratora. Nie znam sposobu na rozgłaszanie wiadomości systemu Windows z partii systemu Windows, więc musisz napisać mały program, aby to zrobić.

David Heffernan
źródło
1
Ok, więc biorąc pod uwagę twoje rozwiązanie, utworzyłem plik rejestru (.reg) zawierający zmienne środowiskowe, które chcę dodać / zmienić. Następnie uruchomię ten plik na wszystkich docelowych komputerach. Naprawdę nie muszę wysyłać wiadomości systemu Windows, ponieważ po prostu uruchomię ponownie aplikację, na którą wpłynie to. Dzięki.
Arthur
1
Dodaję
1
@David, więc dlaczego nie setxponiżej?
Pacerier
Myślę, że ten reg ma tę zaletę, że nie
skraca
2
' SetVar.vbs
Sub sety(wsh, action, typey, vary, value)
  Dim wu
  Set wu = wsh.Environment(typey)
  wui = wu.Item(vary)
  Select Case action
    Case "ls"
      WScript.Echo wui
    Case "del"
      On Error Resume Next
      wu.remove(vary)
      On Error Goto 0
    Case "set"
      wu.Item(vary) = value
    Case "add"
      If wui = "" Then
        wu.Item(vary) = value
      ElseIf InStr(UCase(";" & wui & ";"), UCase(";" & value & ";")) = 0 Then
        wu.Item(vary) = value & ";" & wui
      End If
    Case Else
      WScript.Echo "Bad action"
  End Select
End Sub

Dim wsh, args
Set wsh = WScript.CreateObject("WScript.Shell")
Set args = WScript.Arguments
Select Case WScript.Arguments.Length
  Case 3
    value = ""
  Case 4
    value = args(3)
  Case Else
    WScript.Echo "Arguments - 0: ls,del,set,add; 1: user,system, 2: variable; 3: value"
    value = "```"
End Select
If Not value = "```" Then
  ' 0: ls,del,set,add; 1: user,system, 2: variable; 3: value
  sety wsh, args(0), args(1), UCase(args(2)), value
End If
Justin Peal
źródło
21
Powinieneś rozważyć dodanie kontekstu lub wyjaśnienia do kodu.
adamdunson
1
Potężny kawałek kodu +1. Działa na XP bez setx(i bez możliwości instalacji). Proste użycie (w moim przypadku):wsh.Environment("user").Item("myVar") = "my value"
Marek
2
Ponieważ nikt nie zadał sobie trudu, aby używać na XP (nie wymaga Resource Kit ani setx), aby wykonać {set foo = bar} dla wszystkich (innych) okien DOS: 1. Zapisz powyższy kod jako SetVar.vbs 2. setvar. vbs set system foo "bar" Uwaga, bieżące okno DOS nie otrzymuje FOO z tego. Ustawiono problem foo = bar, aby to osiągnąć
MicrosoftShouldBeKickedInNuts
2
Uwaga również, to przetrwa ponowne uruchomienie (gdy używasz parm systemowego)
MicrosoftShouldBeKickedInNuts
1

Rzeczywiście SET TEST_VARIABLE = wartość działa tylko dla bieżącego procesu, więc SETXjest wymagana. Szybki przykład trwałego przechowywania zmiennej środowiskowej na poziomie użytkownika.

  1. W cmd, SETX TEST_VARIABLE etc . Jeszcze nie zastosowano ( echo %TEST_VARIABLE%programy %TEST_VARIABLE%,
  2. Szybkie sprawdzenie: otwórz cmd, echo %TEST_VARIABLE%pokazuje etc.
  3. Kontrola GUI: Właściwości systemu -> Zaawansowane -> Zmienne środowiskowe -> Zmienne użytkownika dla -> powinieneś zobaczyć Zmienna TESTOWA_ZMIENNA z wartością etc.
Alexei
źródło
0
:: Sets environment variables for both the current `cmd` window 
::   and/or other applications going forward.
:: I call this file keyz.cmd to be able to just type `keyz` at the prompt 
::   after changes because the word `keys` is already taken in Windows.

@echo off

:: set for the current window
set APCA_API_KEY_ID=key_id
set APCA_API_SECRET_KEY=secret_key
set APCA_API_BASE_URL=https://paper-api.alpaca.markets

:: setx also for other windows and processes going forward
setx APCA_API_KEY_ID     %APCA_API_KEY_ID%
setx APCA_API_SECRET_KEY %APCA_API_SECRET_KEY%
setx APCA_API_BASE_URL   %APCA_API_BASE_URL%

:: Displaying what was just set.
set apca

:: Or for copy/paste manually ...
:: setx APCA_API_KEY_ID     'key_id'
:: setx APCA_API_SECRET_KEY 'secret_key'
:: setx APCA_API_BASE_URL   'https://paper-api.alpaca.markets'
gseattle
źródło