Establecer una variable de entorno persistente desde cmd.exe

123

Tengo que establecer variables de entorno en diferentes máquinas con Windows, pero no quiero que me molesten en cambiarlas manualmente accediendo a la pantalla de propiedades de "Mi PC".

Quiero hacerlo desde la línea de comandos, con un archivo por lotes. Por lo que tengo entendido, el uso de set solo cambiará la variable para los procesos que llamaré en la ventana de comandos.

Quiero configurarlo definitivamente, así que más tarde, cuando ejecute un nuevo proceso, usará las nuevas configuraciones que he establecido. ¿Hay alguna forma de hacerlo desde la línea de comandos?

Arturo
fuente
¿Cuál es el punto de configurarlos desde la línea de comando si se vuelven permanentes? No necesitará volver a hacerlo.
d-live
12
Sí, pero tengo que hacerlo en varias computadoras, por lo que ejecutar el script me ahorrará algo de tiempo.
Arthur
2
Ok, en ese caso puede configurar su env en una computadora y hacer una exportación de las entradas que se describen a continuación y tener un archivo .reg, si SETX no está disponible para usted.
d-live
Eso es lo que hice. Gracias.
Arthur
1
RE: '¿Cuál es el punto de configurarlos desde la línea de comando ...?' Donde trabajo hay un requisito constante de una serie de variables ambientales persistentes a diferentes valores para probar / desarrollar diferentes versiones del software. La licencia significa que no se puede hacer de otra manera (por ejemplo, ejecutando una máquina virtual), por lo que nuestro único recurso es usar SETX en un script por lotes. Usar .reg es menos bueno ya que es más difícil documentar / ver exactamente lo que está sucediendo
Tony Eastwood

Respuestas:

189

Use el comando SETX (tenga en cuenta el sufijo 'x') para establecer variables que persisten después de que se haya cerrado la ventana cmd.

Por ejemplo, para establecer un env var "foo" con el valor de "bar":

setx foo bar

Aunque vale la pena leer las 'notas' que se muestran si imprime el uso ( setx /?), en particular:

2) En un sistema local, las variables creadas o modificadas por esta herramienta estarán disponibles en las ventanas de comandos futuras, pero no en la ventana de comandos CMD.exe actual.

3) En un sistema remoto, las variables creadas o modificadas por esta herramienta estarán disponibles en la próxima sesión de inicio de sesión.

En PowerShell, el comando [Environment] :: SetEnvironmentVariable .

Vik David
fuente
Parece que SETX solo está disponible en Windows XP SP2
Arthur
2
Funcionó en Windows 7 para mí. ¿Qué versión de Windows estás usando?
Vik David
@jules: Entonces, puede obtenerlo del Kit de recursos.
Joey
46
Tenga cuidado con SETX, trunca su longitud variable a 1024 caracteres ... muy peligroso al manipular% path%.
Etienne Desgagné
2
con Power Shell, puede [Environment]::SetEnvironmentVariable('PATH', "Whatever you need it to be", "Machine")ver msdn.microsoft.com/en-us/library/96xafkes(v=vs.110).aspx
Gradient
21

La documentación de MSDN para variables de entorno le indica qué hacer:

Para agregar o modificar variables de entorno del sistema mediante programación, agréguelas a la clave de registro HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment , luego transmita un mensaje WM_SETTINGCHANGE con lParam configurado en la cadena "Environment". Esto permite que las aplicaciones, como el shell, recojan sus actualizaciones.

Por supuesto, necesitará derechos de administrador para hacer esto. No conozco ninguna forma de transmitir un mensaje de Windows desde un lote de Windows, por lo que deberá escribir un pequeño programa para hacer esto.

David Heffernan
fuente
1
Ok, considerando su solución, he creado un archivo de registro (.reg) que contiene las variables de entorno que quiero agregar / cambiar. Luego ejecutaré este archivo en todas las PC de destino. Realmente no necesito enviar un mensaje de Windows, ya que simplemente reiniciaré la aplicación que se verá afectada. Gracias.
Arthur
1
Estoy agregando su otra respuesta aquí, ya que era exactamente lo que estaba buscando cuando me topé con esta pregunta: stackoverflow.com/a/19705691/3543437
kayleeFrye_onDeck
1
@David, ¿por qué no setxpor debajo?
Pacerier
Creo que este registro tiene la ventaja de no truncar y no ser 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
Justin Peal
fuente
21
Debería considerar agregar algo de contexto o una explicación para acompañar su código.
Adamdunson
1
Potente código +1. Funciona en XP sin setx(y sin posibilidad de instalarlo). Uso simple (en mi caso):wsh.Environment("user").Item("myVar") = "my value"
Marek
2
Como nadie se ha tomado la molestia, para usarlo en XP (no se requiere Kit de recursos o setx), para lograr {set foo = bar} para todas (otras) ventanas DOS: 1. guarde el código anterior como SetVar.vbs 2. setvar. vbs set system foo "bar" Nota, la ventana DOS actual no obtiene FOO de esto. Problema establecido foo = bar para lograr eso
MicrosoftShouldBeKickedInNuts
2
Tenga en cuenta también que esto sobrevive al reinicio (cuando usa el parámetro del sistema)
MicrosoftShouldBeKickedInNuts
1

De hecho, SET TEST_VARIABLE = value funciona solo para el proceso actual, por lo que SETXes obligatorio. Un ejemplo rápido para almacenar permanentemente una variable de entorno a nivel de usuario.

  1. En cmd SETX TEST_VARIABLE etc. Aún no se ha aplicado ( echo %TEST_VARIABLE%muestra %TEST_VARIABLE%,
  2. Comprobación rápida: abre cmd, echo %TEST_VARIABLE%muestra etc.
  3. Verificación de GUI: Propiedades del sistema -> Avanzado -> Variables de entorno -> Variables de usuario para -> debería ver Varible TEST_VARIABLE con valor etc.
Alexei
fuente
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
fuente