Por que o Windows não pode manipular uma variável de ambiente no Path?

44

Meu colega e eu temos estações de trabalho Dell idênticas ao Windows XP Professional x64 edition instalado.

A variável de ambiente My Path começa com:

%JAVA_HOME%\bin;...

A variável Path do meu colega inclui o mesmo diretório, especificado usando a mesma variável de ambiente, mas não é o primeiro item em seu Path.

Se eu acessar as propriedades do sistema -> variáveis ​​de ambiente e alterar o valor da minha variável JAVA_HOME, a versão do java encontrada na linha de comando será alterada conforme o esperado. Isso está iniciando uma nova janela do console, para garantir as alterações.

Mas na máquina do meu colega, isso não acontece. Ele continua a encontrar sua versão anterior do Java até trazer sua variável Path e salvá-la (mesmo que ele não faça alterações). (Novamente, é quando se inicia uma nova janela do console.)

Eu tenho observado essa inconsistência no Windows há cerca de 6 meses e estou muito curioso. Temos muitas versões do Windows em nosso escritório, tão raramente tive a chance de ver isso acontecendo em duas máquinas executando exatamente a mesma versão do sistema operacional, até agora.

O quê está causando isto? Por que a máquina dele não reavalia o Path, usando o novo JAVA_HOME, quando o meu faz?

(É porque não é a primeira coisa no caminho? Em caso afirmativo, como poderia ser e por quê? Eu faria mais testes para verificar, mas acho que agora ele está farto disso e gostaria de voltar ao trabalho .)

skiphoppy
fonte
9
Para todos vocês que estão votando para fechar (3 no momento) ... se houver um idiota em algum lugar, um comentário apontando para ele com certeza seria bom. Se não é um tolo ... então me dizer o que você acha que está errado com essa pergunta também seria bom.
Skiphoppy 21/08/09
11
Talvez porque é mais uma questão do sistema do que uma programação, embora tenha um impacto direto na programação, é por isso que eu não votar para fechá-la ... :)
9
Attenion close-nazis: Eu gostaria de promover a visão de que, se uma pergunta for apropriada no Stack Overflow antes de superuser.com e serverfault.com chegarem, ainda será apropriado hoje. Esta é uma questão de programação.
Skiphoppy
Você quer dizer que os programadores são apenas usuários do Windows, que podem ter esse problema? Cala a boca, programador-nazista! Em segundo lugar, antes que um site de perguntas e respostas mais adequado chegasse, você não tinha opção de postar perguntas aqui. A hospitalidade da SO não deve ser um argumento para abusar dela.
Val
Estou vendo isso no Windows 10 - a substituição de variáveis ​​no PATH falhou intermitentemente no trabalho. Ir para Variáveis ​​de ambiente e salvar (sem alterações) e abrir um novo prompt de CMD resolveu o problema.
Thomas W

Respostas:

37

Seu caminho é a concatenação do caminho do sistema seguido pelo caminho do usuário. Além disso, as variáveis ​​de ambiente do sistema podem não conter referências a variáveis ​​de ambiente do usuário e essas referências não serão expandidas. Para obter o resultado desejado, insira a referência a% JAVA_HOME% na variável de ambiente do usuário PATH ou crie uma variável se ela ainda não existir.

Talvez um exemplo simplificado torne isso mais claro. Suponha que o ambiente SYSTEM seja

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

e o ambiente do usuário JSmith é

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

então o caminho resultante seria

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

como desejado.

JPaget
fonte
3
Meu sistema tinha algumas variáveis ​​env do usuário com o mesmo nome de algumas variáveis ​​env do sistema. O eco do PATH não os expandiu - depois de ler isso, eu removi as variáveis ​​de usuário duplicadas, pois me perguntava se elas eram escolhidas com precedência (mas não podiam ser expandidas). Isso agora funcionou para mim - muito obrigado. :) #
Michael #
Existe uma maneira via Powershell de obter o CAMINHO não expandido original? Eu esperava anexar ao meu PATH, preservando as variáveis ​​de ambiente não expandidas nele.
CMCDragonkai
Resolvi com alguma ajuda de outra pergunta. Escreva um script do PowerShell para lidar com isso: gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai
16

Faça check-in no registro do Windows com esta chave:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

SE a variável de ambiente precisar ser expandida (aqui:% JAVA_HOME%)

a variável deve ser definida como um valor REG_EXPAND_SZ .

Se estiver usando o reg.exe por meio da linha de comando para adicionar / editar valores do Registro, o padrão é digitar REG_SZ. Especifique o tipo REG_EXPAND_SZ usando a reg add /t REG_EXPAND_SZopção.

climenole
fonte
sim ... este é um daqueles definições que eu sempre parecem esquecer ... Registro traquinas ;-)
Eddie B
9

Há um problema definido com a expansão de variáveis ​​de ambiente na variável PATH quando a variável se expande para um caminho que contém espaços.

Criamos nossas próprias variáveis ​​no nível do sistema, como "OUR_ROOT = c: \ MyRoot" e, em seguida, usamos no PATH do sistema como "PATH =;% OUR_ROOT% \ bin;" e que é expandido corretamente para "PATH =; c: \ MyRoot \ bin;". Até agora não há problema.

Mas, no Windows 7 (32 bits), eu tinha um produto instalado e criava variáveis ​​de ambiente do sistema como esta:

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

e adicionou à variável PATH do sistema:

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

Mas os valores PATH mostrados no CMD continham "% STUDIO_BIN%;" e não o caminho expandido. O valor em Meu computador> Propriedades> Avançado> Env.Vars também permaneceu não expandido. Isso significava que não podia executar programas que exigiam uma DLL nesse diretório.

Alterando apenas STUDIO_BIN (via Meu computador> Propriedades> Avançado ...> Env Vars) para um nome sem espaços incorporados:

STUDIO_BIN=C:\ProductName\bin

e, em seguida, reiniciando a janela CMD, o PATH é agora:

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

Outra solução é editar suficientemente a variável do sistema que você está usando no PATH usando o diálogo Meu Computador> Propriedades> Avançado ...> Variáveis ​​de Ambiente. Tentei adicionar um caractere e removê-lo para fazer uma 'alteração' e, em seguida, sair OK, iniciei um novo prompt de CMD e PATH NÃO foi expandido corretamente. Tentei excluir parte do caminho para que ele fosse

STUDIO_BIN=C:\Program Files\Company Name

(omitindo "Nome do produto 10.4") e eis que o próximo prompt do CMD mostrou PATH com STUDIO_BIN expandido corretamente!

Estranhamente, se eu voltasse e adicionasse o "Product Name 10.4" ao STUDIO_BIN (incluindo todos os espaços que estavam originalmente lá antes de começar a mexer com ele) e PATH AINDA continuaria sendo expandido corretamente.

Evidentemente, com alterações suficientes em seu conteúdo, a variável PATH passa por um processamento extra na caixa de diálogo Variáveis ​​de ambiente que permite que ela funcione. O processamento não é feito quando a variável foi adicionada pelo instalador do produto (que provavelmente apenas modificou o PATH no registro diretamente).

Estou quase certo de que este foi um problema com o XP também. Ele apenas ressurgiu para mim no Windows 7, quando eu estava montando uma nova máquina de desenvolvimento. Aparentemente, não foi corrigido pela Microsoft.

Aparentemente, até as variáveis ​​definidas pelo MS, como% ProgramFiles%, não serão expandidas corretamente no PATH.

Esta página fornece uma resposta possível se você estiver configurando o PATH por meio da linha de comando ou arquivo em lote. (Coloque o comando inteiro após SET entre aspas.) Não sei qual instalador o produto que eu instalei utilizou para definir as variáveis ​​de ambiente, mas evidentemente passou por todo o processamento necessário para expandir adequadamente os caminhos com espaços.

Então - para resumir, você pode:

  • alterar os caminhos (e mover todos os arquivos associados) para caminhos sem espaços, ou

  • edite as variáveis ​​que não estão conseguindo se expandir na caixa de diálogo Variáveis ​​de ambiente (alterando-as o suficiente para que elas sejam processadas corretamente - não sei o quanto é suficiente).

RobDavenport
fonte
7

Eu perguntei isso nos fóruns da Microsoft em março de 2009 e nunca resolvi:

Como usar% ProgramFiles% na variável de ambiente Path? :


Estou tentando adicionar uma pasta à variável de ambiente Path do sistema.

eu quero adicionar % ProgramFiles% \ SysInternals

para a variável de caminho existente:

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

Então eu vou no lugar onde você o edita:

texto alternativo

E adiciono minha variável ao caminho:

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

Ao abrir uma nova janela do prompt de comando, a variável de ambiente não é substituída pelo seu valor real:

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

Que você pode ver na seguinte captura de tela:

texto alternativo


Mas para responder sua pergunta: eu não sei. Parece que não pode ser feito.

Ian Boyd
fonte
5

existem dois níveis de variáveis ​​de ambiente, global e usuário. Se ele tiver% Java_home% definido como uma variável de ambiente do usuário, mas estiver alterando a global, ele não verá nenhuma diferença.

Sekhat
fonte
2

Verifique se não há espaços no PATH ao definir suas próprias variáveis ​​de ambiente do usuário. por exemplo: C: \ GNAT \ bin; C: \ GNAT \ include não funcionará, devido ao espaço entre o ";" e "C: \ GNAT \ include".

Nij
fonte
2

Adicione as variáveis ​​de ambiente enquanto estiver conectado à sessão / console usando o MSTSC.

Reinicie a máquina e você descobrirá que suas variáveis ​​de ambiente persistiram.

Parece haver uma peculiaridade no sistema operacional, dependendo de como você estava conectado à máquina quando tentou alterar a variável de ambiente.

Justin
fonte
1

Pode estar relacionado ao recurso "expansão de variável de ambiente atrasada" (ou à falta dele) ou talvez você possa aproveitar esse recurso para sempre ter uma solução correta.

de um prompt de cmd

set /? 

e leia a seção que descreve "expansão atrasada da variável de ambiente", que inclui um pequeno exemplo para testar

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

Se você não receber a linha de eco, isso pode explicar ...

Se, no entanto, você iniciar o cmd.exe com a opção / V, poderá usar "!" em vez de "%", que altera o comportamento

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

Para mim (executando no XP), o primeiro script não funcionou, mas a segunda versão funcionou (com cmd.exe / V)

libjack
fonte
1

Eu tive o mesmo problema e sei como consertá-lo, é manco.

Apenas edite seu PATH novamente, mas não faça alterações e salve novamente o PATH. Por alguma razão, isso faz com que todas as referências de variáveis ​​de ambiente aninhadas sejam reavaliadas.

Se não funcionar, faça-o mais algumas vezes, de alguma forma simplesmente funcionará.

BAP
fonte
1

Eu acredito que o Windows falha ao expandir uma variável no PATH porque pensa o que ainda não foi definido. Considerar:

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

Essa hipótese está de acordo com minha outra observação - adicionar %ProgramFiles%\Somethingaos usuários PATH sempre resultará na expansão esperada de %ProgramFiles%, uma vez que ela foi definida no ambiente da máquina no momento da notificação de alteração variável (ordem de carregamento devido - MACHINE e, em seguida, USUÁRIO). Porém, quando você modifica o ambiente da máquina, a expansão correta das variáveis ​​ocorre apenas no momento da inicialização (no momento não tenho idéia de como e por que isso não ocorre regularmente).

user539484
fonte
1

Você deve considerar a ordem em que as variáveis ​​são definidas no login. Se você tentar usar uma variável antes que ela seja definida, ela sairá como a sequência vazia.

O PATH efetivo é a concatenação da variável PATH do usuário seguida pela variável PATH global.

As variáveis ​​do usuário são definidas antes das variáveis ​​globais, portanto, você não pode usar variáveis ​​globais na variável PATH do usuário. Além disso, as variáveis ​​são definidas em ordem alfabética, portanto, você não pode usar variáveis ​​que classifiquem antes de PATH.

(Isso se aplica ao Windows 7, pelo menos. Não testei isso em versões mais recentes.)

cbarrick
fonte
0

Talvez você esteja fazendo errado?

Eu tentei com o Windows XP Pro SP3 (32 bits). Eu tenho um caminho com várias ocorrências de %JAVA_HOME%(e %JAVAFX_HOME%, etc.). Eu vou para a linha de comando, digite PATH, vejo as variáveis ​​expandidas. Boa.

Eu mudo o valor de JAVA_HOME. De volta à mesma janela da linha de comando, PATHnovamente, o mesmo valor ... conforme o esperado (por experiência!).

Abro uma nova janela de linha de comando, digite PATH, peguei, vejo o novo valor.

Não tenho certeza de qual é o mecanismo exato, mas parece que qualquer programa em execução, incluindo o cmd.exe, captura os valores das variáveis ​​de ambiente na hora de iniciar e não olha para trás ... (embora eu acredite que um bom programa comportado possa ouça as alterações de ambiente, mas não tenho muita certeza).

Pode ser visto como um recurso ou um bug ou aborrecimento, mas é assim que funciona. Ei, pelo menos, ao contrário do Win9X, não precisamos reiniciar o computador! E, diferentemente dos tempos do NT (IIRC), você não precisa sair e voltar.

Por que a inconsistência? Os caminhos da Microsoft são inescrutáveis ​​... :-P

PhiLho
fonte
Não é isso. Após a alteração, estamos testando em uma nova janela de comando. Estamos cientes do fato de que alterar os valores do sistema não altera os valores dos processos em execução.
Skiphoppy
OK, daí o 'talvez' ... :-) E minha explicação não cobre a inconsistência, mas pode ser útil para um novato ...: -PI principalmente queria apontar que a expansão variável funciona em qualquer lugar do caminho. .. para alguns sistemas! (todos aqueles que eu usei ... sempre 32 bits).
0

Resolvi definir as variáveis ​​de ambiente em Sistema> Configurações avançadas> Variáveis ​​de ambiente .

Existem dois painéis: Variáveis ​​de usuário e globais (usuário é o nome de usuário do Windows) e Variáveis ​​de sistema são variáveis ​​globais. Portanto, se você definir 'Novo' em Variáveis ​​de usuário, como JAVA_HOMEe colocar seu caminho abaixo, definirá variáveis ​​mesmo que seu caminho global tem arquivos de programa dentro da pasta.

thunder_nemesis
fonte