¿Por qué Windows no puede manejar una variable de entorno en Path?

44

Mi colega y yo tenemos estaciones de trabajo idénticas de Dell con la edición Windows XP Professional x64 instalada.

La variable de entorno My Path comienza con:

%JAVA_HOME%\bin;...

La variable de ruta de mi colega incluye el mismo directorio, especificado usando la misma variable de entorno, pero no es el primer elemento de su ruta.

Si accedo a las propiedades del sistema -> variables de entorno y cambio el valor de mi variable JAVA_HOME, la versión de java que se encuentra en la línea de comandos cambia como esperaba. Esto está iniciando una nueva ventana de consola, para asegurarse de recoger los cambios.

Pero en la máquina de mi colega, no lo hace. Continúa buscando su versión anterior de Java hasta que aparezca su variable Path y la guarde (incluso si no la modifica). (Nuevamente, esto es cuando se inicia una nueva ventana de consola).

He estado observando esta inconsistencia en Windows durante aproximadamente 6 meses y tengo mucha curiosidad al respecto. Tenemos demasiadas versiones de Windows en nuestra oficina, así que rara vez he tenido la oportunidad de ver que esto suceda en dos máquinas que ejecutan exactamente la misma versión del sistema operativo, hasta ahora.

¿Qué está causando esto? ¿Por qué su máquina no vuelve a evaluar Path, usando el nuevo JAVA_HOME, cuando el mío sí?

(¿Es porque no es lo primero en el Camino? Si es así, ¿cómo podría ser eso y por qué? Haría más pruebas para verificar, pero creo que ahora está harto de eso y me gustaría volver a trabajar .)

skiphoppy
fuente
99
Para todos ustedes que votan para cerrar (3 en este momento) ... si hay un duplicado en alguna parte, un comentario que me señale seguramente sería bueno. Si no es un engaño ... entonces decirme qué crees que está mal con esta pregunta también sería bueno.
skiphoppy
1
Quizás porque es más una cuestión de sistema que una de programación, aunque tiene un impacto directo en la programación, por eso no voto para cerrarla ... :)
99
Atención, nazis cercanos: Me gustaría promover la opinión de que si una pregunta era apropiada en Stack Overflow antes de que llegaran superuser.com y serverfault.com, entonces todavía es apropiada hoy. Esta es una pregunta de programación.
skiphoppy
¿Quiere decir que los programadores son solo usuarios de Windows, que pueden tener este problema? ¡Cállate, programador-nazi! En segundo lugar, antes de que llegara un sitio de preguntas y respuestas más apropiado, no tenía la opción de publicar preguntas aquí. La hospitalidad de SO no debe ser un argumento para abusar de él.
Val
Estoy mirando esto en Windows 10: la sustitución de variables en PATH no funcionó de forma intermitente . Ir a Variables de entorno y guardar (sin cambios) y luego abrir un nuevo indicador CMD resolvió el problema.
Thomas W

Respuestas:

37

Su ruta es la concatenación de la ruta del sistema seguida de la ruta del usuario. Además, las variables de entorno del sistema pueden no contener referencias a las variables de entorno del usuario, y dichas referencias no se expandirán. Para obtener el resultado deseado, inserte la referencia a% JAVA_HOME% en la variable de entorno de usuario PATH, o cree dicha variable si aún no existe.

Quizás un ejemplo simplificado aclarará esto. Supongamos que el entorno del SISTEMA es

ProgramFiles = C:\Program Files
SystemRoot = C:\WINDOWS
PATH = %SystemRoot%\SYSTEM32

y el entorno del usuario JSmith es

JAVA_HOME = %ProgramFiles%\Java\bin
USERPROFILE = C:\USERS\JSmith
PATH = %JAVA_HOME%\bin;%USERPROFILE%\bin

entonces la ruta resultante sería

C:\WINDOWS\SYSTEM32;C:\Program Files\Java\bin;C:\Users\JSmith\bin

como se desee.

JPaget
fuente
3
Mi sistema tenía algunas variables env del usuario con el mismo nombre que algunas variables env del sistema. Echoing PATH no los expandiría: después de leer esto, eliminé las variables de usuario duplicadas ya que me preguntaba si se recogieron con prioridad (pero no se pueden expandir). Esto ahora ha funcionado para mí, muchas gracias. :)
Michael
¿Hay alguna manera a través de Powershell para obtener la RUTA original sin expandir? Esperaba agregar a mi RUTA mientras conservaba las variables de entorno no expandidas en ella.
CMCDragonkai
Lo resolvió con la ayuda de otra pregunta. Escriba un script de PowerShell
CMCDragonkai
16

Compruebe en el registro de Windows con esta clave:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

SI la variable de entorno necesita expandirse (aquí:% JAVA_HOME%)

entonces la variable debe establecerse como un valor REG_EXPAND_SZ .

Si usa reg.exe a través de la línea de comandos para agregar / editar valores de registro, el valor predeterminado es escribir REG_SZ. Especifique el tipo REG_EXPAND_SZ utilizando la reg add /t REG_EXPAND_SZopción

climenole
fuente
sí ... esta es una de esas configuraciones que siempre parece olvidar ... registro molesto ;-)
Eddie B
9

Existe un problema definido con la expansión de las variables de entorno dentro de la variable PATH cuando la variable se expande a una ruta que contiene espacios.

Creamos nuestras propias variables de nivel de sistema como "OUR_ROOT = c: \ MyRoot" y luego lo usamos en la RUTA del sistema como "PATH =;% OUR_ROOT% \ bin;" y eso se expande correctamente a "PATH =; c: \ MyRoot \ bin;". Hasta ahora no hay problema.

Pero, en Windows 7 (32 bits), hice que un producto se instalara y creara variables de entorno del sistema como esta:

STUDIO_BIN=C:\program files\Company Name\Product Name 10.4\bin

y lo agregó a la variable PATH del sistema:

PATH=<other path elements>;%STUDIO_BIN%;<more path elements>

Pero los valores PATH que se muestran en CMD contenían "% STUDIO_BIN%;" y no el camino expandido. El valor en Mi PC> Propiedades> Avanzado> Env.Vars también permaneció sin expandir. Esto significaba que no podía ejecutar programas que requerían una DLL en ese directorio.

Simplemente cambiando STUDIO_BIN (a través de Mi PC> Propiedades> Avanzado ...> Env Vars) a un nombre sin espacios incrustados:

STUDIO_BIN=C:\ProductName\bin

y luego reiniciando la ventana CMD, la RUTA ahora es:

PATH=<other path elements>;C:\ProductName\bin;<more path elements>

Otra solución es editar suficientemente la variable del sistema que está utilizando en la RUTA utilizando el cuadro de diálogo Mi PC> Propiedades> Avanzado ...> Variables de entorno. Traté de agregar un personaje y eliminarlo para hacer un 'cambio' y luego salí bien, comencé un nuevo mensaje CMD y PATH NO se expandió correctamente. Luego intenté eliminar parte de la ruta para que fuera

STUDIO_BIN=C:\Program Files\Company Name

(omitiendo "Nombre del producto 10.4") y he aquí, y el siguiente mensaje CMD mostró PATH con STUDIO_BIN correctamente expandido.

Por extraño que parezca, si volví a entrar y agregué el "Nombre del producto 10.4" a STUDIO_BIN (incluidos todos los espacios que originalmente estaban allí antes de que empezara a jugar con él) y la RUTA TODAVÍA se expandió correctamente.

Evidentemente, con suficientes cambios en su contenido, la variable PATH se somete a un procesamiento adicional en el cuadro de diálogo Variables de entorno que le permite funcionar. Procesamiento que no se realiza cuando el instalador del producto agregó la variable (que probablemente solo modificó la RUTA directamente en el registro).

Estoy casi seguro de que esto también fue un problema con XP. Simplemente resurgió para mí en Windows 7 cuando estaba armando una nueva máquina de desarrollo. Al parecer, no ha sido reparado por Microsoft.

Aparentemente, incluso las variables definidas por MS como% ProgramFiles% no se expandirán correctamente en la RUTA.

Esta página proporciona una posible respuesta si está configurando PATH a través de la línea de comandos o el archivo por lotes. (Incluya todo el comando después de SET entre comillas). No sé qué instalador usó el producto que instalé para configurar las variables de entorno, pero evidentemente dio la vuelta al procesamiento que sea necesario para expandir adecuadamente las rutas con espacios.

Entonces, para resumir, puedes:

  • cambiar las rutas (y mover todos los archivos asociados) a rutas sin espacios, o

  • edite las variables que no se expanden en el cuadro de diálogo Variables de entorno (cambiándolas lo suficiente como para que se procesen correctamente; no estoy seguro de cuánto es suficiente).

RobDavenport
fuente
7

Lo pregunté en los foros de Microsoft en marzo de 2009 y nunca lo resolví:

¿Cómo usar% ProgramFiles% en la variable de entorno Path? :


Estoy tratando de agregar una carpeta a la variable de entorno Path del sistema.

quiero agregar % ProgramFiles% \ SysInternals

a la variable de ruta existente:

C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Proyectos \ Bpl; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Bin; % SystemRoot% \ system32; % SystemRoot% ;% SystemRoot % \ System32 \ Wbem; C: \ Archivos de programa \ Microsoft SQL Server \ 80 \ Tools \ BINN; C: \ Archivos de programa \ Microsoft SQL Server \ 80 \ Tools \ Binn \; C: \ Archivos de programa \ Microsoft SQL Server \ 90 \ Tools \ binn \; C: \ Archivos de programa \ Microsoft SQL Server \ 90 \ DTS \ Binn \; C: \ Archivos de programa \ Microsoft SQL Server \ 90 \ Tools \ Binn \ VSShell \ Common7 \ IDE \; C: \ Archivos de programa \ Microsoft Visual Studio 8 \ Common7 \ IDE \ PrivateAssemblies \;% SYSTEMROOT % \ System32 \ WindowsPowerShell \ v1.0 \

Así que voy al lugar donde lo editas:

texto alternativo

Y agrego mi variable a la ruta:

% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl; (recorte)

Luego, al abrir una nueva ventana del símbolo del sistema, la variable de entorno no se reemplaza con su valor real:

Ruta =% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl (snip)>

Que puedes ver en la siguiente captura de pantalla:

texto alternativo


Pero para responder a su pregunta: no lo sé. Parece que no se puede hacer.

Ian Boyd
fuente
5

Hay dos niveles de variables de entorno, global y de usuario. Si tiene% Java_home% establecido como una variable de entorno de usuario pero en cambio está cambiando la global, no verá ninguna diferencia.

Sekhat
fuente
2

Asegúrese de que no haya espacios en la RUTA cuando defina sus propias variables de entorno de usuario. por ejemplo: C: \ GNAT \ bin; C: \ GNAT \ include no funcionará, debido al espacio entre ";" y "C: \ GNAT \ include".

Nij
fuente
2

Agregue las variables de entorno mientras está conectado a la sesión / consola usando MSTSC.

Reinicie la máquina y encontrará que las variables de entorno habrán persistido.

Parece haber una peculiaridad en el O / S dependiendo de cómo estaba conectado a la máquina cuando intentó cambiar la variable de entorno.

Justin
fuente
1

Puede estar relacionado con la función de "expansión de variable de entorno retrasada" (o falta de ella), o quizás puede aprovechar esta característica para tener siempre una solución correcta.

desde un indicador de cmd

set /? 

y lea la sección que describe la "expansión retardada de la variable de entorno", que incluye un pequeño ejemplo para probar

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

Si no obtiene la línea de eco, eso podría explicarlo ...

Sin embargo, si inicia su cmd.exe con la opción / V, puede usar "!" en lugar de "%", que cambia el comportamiento

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

Para mí (ejecutándose en XP), el primer script no funcionó, pero la segunda versión sí (con cmd.exe / V)

libjack
fuente
1

He tenido el mismo problema y sé cómo solucionarlo, es lamentable.

Simplemente edite su RUTA nuevamente, pero no realice ningún cambio y vuelva a guardar la RUTA. Por alguna razón, esto hace que todas las referencias de variables de entorno anidadas se vuelvan a evaluar.

Si no funciona, hágalo varias veces más, de alguna manera simplemente funciona.

PANECILLO EN ESCOCIA
fuente
1

Sí creo que Windows no puede expandir una variable en RUTA porque piensa lo que aún no ha definido. Considerar:

REM Ensure variable is undefined
SET UNDEFINED=
REM And then try to expand it
ECHO UNDEFINED=%UNDEFINED%

Esta hipótesis se ajusta a mi otra observación: agregar %ProgramFiles%\Somethinga los usuarios PATH siempre dará como resultado la expansión esperada de %ProgramFiles%, dado que se ha definido en el entorno de la máquina en el momento de la notificación de cambio variable (debido orden de carga - MÁQUINA y luego USUARIO). Pero cuando modifica el entorno de la máquina, la expansión de la variable correcta solo ocurre en el momento del arranque (en este momento no tengo idea de cómo y por qué esto no sucede de manera regular).

usuario539484
fuente
1

Debe tener en cuenta el orden en que se establecen las variables al iniciar sesión. Si intenta usar una variable antes de establecerla, aparecerá como la cadena vacía.

La RUTA efectiva es la concatenación de la variable RUTA del usuario seguida de la variable RUTA global.

Las variables de usuario se establecen antes que las variables globales, por lo que no puede usar variables globales en su variable PATH de usuario. Además, las variables se establecen en orden alfabético, por lo que no puede usar variables que se ordenen antes de PATH.

(Esto se aplica al menos a Windows 7. No he probado esto en versiones más recientes).

cbarrick
fuente
0

¿Quizás lo estás haciendo mal?

Intenté con Windows XP Pro SP3 (32 bits). Tengo un camino con varias ocurrencias de %JAVA_HOME%(y %JAVAFX_HOME%, etc.). Voy a la línea de comando, escribo PATH, veo las variables expandidas. Bueno.

Yo cambio el valor de JAVA_HOME. Volver a la misma ventana de línea de comando, PATHnuevamente, el mismo valor ... como se esperaba (¡por experiencia!).

Abro una nueva ventana de línea de comandos PATH, tecleo, tengo, veo el nuevo valor.

No estoy seguro de cuál es el mecanismo exacto allí, pero parece que cualquier programa en ejecución, incluido cmd.exe, captura los valores de las variables de entorno en el momento de inicio y no mira hacia atrás ... (aunque creo que un programa con buen comportamiento puede escuche los cambios ambientales, aunque no estoy muy seguro).

Puede verse como una característica o un error o molestia, pero así es como funciona. Hola, al menos, a diferencia de Win9X veces, ¡no tenemos que reiniciar la computadora! Y a diferencia de NT times (IIRC), no tiene que cerrar sesión y volver.

¿Por qué la inconsistencia? Las formas de Microsoft son inescrutables ... :-P

PhiLho
fuente
Esto no lo es. Después del cambio, estamos probando en una nueva ventana de comandos. Somos conscientes del hecho de que cambiar los valores del sistema no cambia los valores para los procesos en ejecución.
skiphoppy
OK, de ahí el 'quizás' ... :-) Y mi explicación no cubre la inconsistencia, pero podría ser útil para algunos novatos ...: -PI en su mayoría quería señalar que la expansión variable funciona en todas partes en el camino. .. para algunos sistemas! (Todos los que usé ... siempre 32 bits).
0

He resuelto configurar las variables de entorno en Sistema> Configuración avanzada> Variables de entorno .

Hay dos paneles, Usuario y Variables globales (el usuario es su nombre de usuario de Windows) y las Variables del sistema son Variables globales, por lo que si configura 'Nuevo' desde Variables de usuario, como JAVA_HOMEy coloca su ruta a continuación, establecerá variables incluso si su ruta global tener archivos de programa dentro de la carpeta.

thunder_nemesis
fuente