Imposta una variabile di ambiente persistente da cmd.exe


123

Devo impostare le variabili d'ambiente su diverse macchine Windows, ma non voglio essere disturbato a cambiarle manualmente entrando nella schermata delle proprietà di "Risorse del computer"

Voglio farlo dalla riga di comando, con un file batch. Per quanto ho capito, l'uso di set cambierà solo la variabile per i processi che chiamerò nella finestra di comando.

Voglio impostarlo definitivamente, quindi in seguito, quando si esegue un nuovo processo, utilizzerà le nuove impostazioni che ho impostato. C'è un modo per farlo dalla riga di comando?


Qual è il punto di impostarli dalla riga di comando se stanno diventando permanenti? Non avrai bisogno di farlo di nuovo.
d-live

12
Sì, ma devo farlo su diversi computer, quindi eseguire lo script mi ​​farà risparmiare tempo.
Arthur

2
Ok, in quel caso puoi impostare il tuo env su un computer ed esportare le voci descritte di seguito e avere un file .reg, se SETX non è disponibile.
d-live

È quello che ho fatto. Grazie.
Arthur

1
RE: "Qual è lo scopo di impostarli dalla riga di comando ..." Dove lavoro c'è un requisito costante di un numero di variabili ambientali persistenti a valori diversi al fine di testare / sviluppare diverse versioni del software. La concessione della licenza significa che non può essere fatto in nessun altro modo (ad esempio, eseguire una VM), quindi la nostra unica risorsa è usare SETX in uno script batch. Usare .reg è meno buono in quanto è più difficile documentare / vedere esattamente cosa sta succedendo
Tony Eastwood

Risposte:


189

Utilizzare il comando SETX (notare il suffisso "x") per impostare le variabili che persistono dopo che la finestra di cmd è stata chiusa.

Ad esempio, per impostare un env var "foo" con valore "bar":

setx foo bar

Anche se vale la pena leggere le 'note' che vengono visualizzate se si stampa il use ( setx /?), in particolare:

2) Su un sistema locale, le variabili create o modificate da questo strumento saranno disponibili nelle finestre di comando future ma non nella finestra di comando CMD.exe corrente.

3) Su un sistema remoto, le variabili create o modificate da questo strumento saranno disponibili alla successiva sessione di accesso.

In PowerShell, il comando [Environment] :: SetEnvironmentVariable .


Sembra che SETX sia disponibile solo su Windows XP SP2
Arthur

2
Ha funzionato su Windows 7 per me. Quale versione di Windows stai usando?
Vik David

@jules: Puoi ottenerlo dal Resource Kit, allora.
Joey

46
Fai attenzione con SETX, tronca la tua lunghezza variabile a 1024 caratteri ... molto pericoloso quando si manipola% path%.
Etienne Desgagné

2
con Power Shell puoi semplicemente [Environment]::SetEnvironmentVariable('PATH', "Whatever you need it to be", "Machine")vedere msdn.microsoft.com/en-us/library/96xafkes(v=vs.110).aspx
Gradient

21

La documentazione di MSDN per le variabili di ambiente indica cosa fare:

Per aggiungere o modificare a livello di codice le variabili di ambiente di sistema, aggiungerle alla chiave di registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment , quindi trasmettere un messaggio WM_SETTINGCHANGE con lParam impostato sulla stringa "Environment". Ciò consente alle applicazioni, come la shell, di raccogliere i tuoi aggiornamenti.

Ovviamente avrai bisogno dei diritti di amministratore per farlo. Non conosco alcun modo per trasmettere un messaggio di Windows dal batch di Windows, quindi dovrai scrivere un piccolo programma per farlo.


1
Ok, quindi considerando la tua soluzione, ho creato un file di registro (.reg) contenente le variabili d'ambiente che voglio aggiungere / modificare. Quindi eseguirò questo file su tutti i PC di destinazione. Non ho davvero bisogno di inviare un messaggio di Windows, poiché riavvierò semplicemente l'applicazione che sarà interessata. Grazie.
Arthur

1
Sto aggiungendo l'altra risposta qui, come è stato esattamente quello che stavo cercando quando sono incappato in questa domanda: stackoverflow.com/a/19705691/3543437
kayleeFrye_onDeck

1
@ David, quindi perché non setxper sotto?
Pacerier

Penso che questo registro abbia il vantaggio di non troncare e non essere powershell
eri0o

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

21
Dovresti considerare l'aggiunta di un contesto o una spiegazione per accompagnare il tuo codice.
adamdunson

1
Potente pezzo di codice +1. Funziona su XP senza setx(e senza possibilità di installarlo). Uso semplice (nel mio caso):wsh.Environment("user").Item("myVar") = "my value"
Marek

2
Dato che nessuno si è preso la briga di usarlo su XP (nessun Resource Kit o setx richiesto), per eseguire {set foo = bar} per tutte le (altre) finestre DOS: 1. salvare il codice sopra come SetVar.vbs 2. setvar. vbs set system foo "bar" Nota, la finestra DOS corrente non riceve FOO da questo. Problema impostato foo = bar per raggiungere questo obiettivo
MicrosoftShouldBeKickedInNuts

2
Nota anche, questo sopravvive al riavvio (quando usi il parametro di sistema)
MicrosoftShouldBeKickedInNuts

1

Infatti SET TEST_VARIABLE = value funziona solo per il processo corrente, quindi SETXè obbligatorio. Un rapido esempio per memorizzare in modo permanente una variabile di ambiente a livello di utente.

  1. In cmd SETX TEST_VARIABLE etc. Non ancora applicato ( echo %TEST_VARIABLE%mostra %TEST_VARIABLE%,
  2. Controllo rapido: apri cmd, echo %TEST_VARIABLE%mostra etc.
  3. Controllo GUI: Proprietà di sistema -> Avanzate -> Variabili d'ambiente -> Variabili utente per -> dovresti vedere Varible TEST_VARIABLE con valore etc.

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'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.