Normalmente, se eu definir uma variável de ambiente do Windows 10 do usuário (var 1) em termos de outra (var 2), a var 2 deve preceder a var 1 em ordem alfabética para que funcione. Isso é identificado aqui , por exemplo
Por exemplo, na janela
isto
APYTHONDIR -> C:\Users\user1\myprogs
PATH -> %APYTHONDIR%
funciona, mas isso
PYTHONDIR -> C:\Users\user1\myprogs
PATH -> %PYTHONDIR%
não.
Existe alguma maneira de evitá-lo? Trabalhando em torno disso?
Pretendo obter uma solução que funcione funcionalmente como se as variáveis fossem definidas via registro (ou Painel de Controle).
Sempre posso usar nomenclatura para garantir que as definições "aninhadas" sigam a ordem alfabética. Isto não é o que eu quero.
Pensei em configurá-los na ordem desejada em um arquivo de lote de inicialização ( autoexec.nt
, ou o que for atual). Não tenho certeza se isso funcionaria para qualquer aplicativo que exija as variáveis de ambiente. Por exemplo, integração simbólica de oitava precisando encontrar python
algum lugar no PATH
, com o diretório PATH
sendo adicionado dessa maneira.
EDIT De acordo com as respostas de harrymc e eu, e seguindo a discussão, foi isso que tentei:
Criar um arquivo
set_env_vars.bat
em um diretório arbitrário e definir um atalho para ele em%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
.Adicionando uma linha
set /P PTEST=Enter value for PTEST
paraset_env_vars.bat
garantir que o arquivo esteja sendo lido durante o logon.Fazendo logoff e logon. Eu verifiquei que
set_env_vars.bat
é lido.
Então, eu adicionei linhas
set ZTEST_DIR=C:\ztest
set YTEST_DIR=%ZTEST_DIR%;C:\ytest
para set_env_vars.bat
. Além disso, faça logoff / logon. Isso não me deu vars ZTEST_DIR
e YTEST_DIR
no meu ambiente.
Então, eu os substituí por linhas
setx ZTEST_DIR C:\ztest
set /P WAITING_DUMMY=Enter value for WAITING_DUMMY
setx YTEST_DIR %ZTEST_DIR%;C:\ytest
em set_env_vars.bat
. (A segunda linha para tentar dar tempo ao sistema para definir a primeira var). Além disso, faça logoff / logon. Isso me deu varios
YTEST_DIR=;C:\ytest
ZTEST_DIR=C:\ztest
no meu ambiente.
Se você fizer isso
set "a=x%b%y"
, entãoa
é definido exatamente assim e%b%
só será expandido quando necessário. É por isso que a ordem alfabética não tem importância. As variáveis são substituídas quando seu valor é necessário ePATH
é um exemplo de um valor que é imediatamente necessário.Para automatizar a configuração de variáveis de ambiente, coloque os comandos SET em um arquivo batch (
.bat
) e copie o arquivo para a pasta Inicialização .Sua pasta de inicialização pessoal deve ser
C:\Users\<user name>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
, enquanto a pasta de inicialização Todos os usuários deve serC:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
.Pergunta: O que estou fazendo abaixo que é diferente do que você faz? Você pode nos mostrar uma captura de tela semelhante se estiver obtendo resultados diferentes.
Quanto ao exemplo que você postou, os resultados são os esperados. Você usou o
setx
comando, que define variáveis de ambiente para o usuário no registro, mas não no ambiente local . Você precisaria iniciar um novo prompt de comando na área de trabalho para se beneficiar dessa variável.O importante aqui é que
setx
funciona no registro, mas não faz com que o ambiente local seja reavaliado. O ambiente é construído apenas uma vez, quando um processo é iniciado, e permanece o mesmo durante toda a execução (a menos que seja modificado localmente pelo próprio processo). Qualquer filho iniciado por um processo pai herdará o ambiente de seu pai, portanto, nenhuma referência é feita nesse caso ao registro.A demonstração abaixo demonstra o problema: A variável é definida no prompt de comando acima, mas não possui um valor local. O prompt de comando inferior é iniciado na área de trabalho e tem esse valor.
Resumindo:
Arquivo de configuração
setvars.cmd
(o nome é arbitrário) no diretório%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
, ou coloquesetvars.cmd
em outro lugar e defina um atalho para ele a partir daí.Nesse arquivo, use (por exemplo)
Testado e funciona. Se o Painel de Controle for usado para definir quaisquer variáveis a partir deste ponto, ele pode atrapalhar as definições aninhadas que não seguem a ordem alfabética .
**tl;dr**
Parece haver pelo menos 3 maneiras alternativas de definir variáveis de ambiente do usuário:
Através do Painel de Controle.
Clique com o botão direito do mouse em computador -> Propriedades -> Configurações avançadas do sistema -> Variáveis de ambiente -> Novo para variáveis de usuário para USER1 -> Digite o nome e o valor da variável -> Ok.
O uso "aninhado" de variáveis é lido em ordem alfabética .
As variáveis também são exibidas em ordem alfabética.
Por meio da edição do registro de
HKEY_CURRENT_USER\Environment
.Tecla do Windows -> reged -> Ir
HKEY_CURRENT_USER\Environment
para a barra de endereço -> Editar -> Novo ->REG_EXPAND_SZ
-> Digite o nome -> Clique com o botão direito do mouse no nome adicionado -> Modificar -> Digite o valor -> Ok.O uso "aninhado" de variáveis é lido na ordem em que foram definidas .
As variáveis são exibidas em ordem alfabética, apenas por conveniência.
Isso responde a pergunta, em princípio. Mas se forem usadas definições "aninhadas" que não seguem a ordem alfabética, a pessoa é "proibida" de usar o método do Painel de Controle novamente, caso contrário, ele impõe a leitura da ordem alfabética e bagunça as definições.
Via linha de comando / arquivo em lote / autoexec.
Conforme detalhado abaixo. Ajudado por esta resposta , com o uso adicional de
SETX var value
em vez de apenasSET var=value
.O uso "aninhado" de variáveis é lido na ordem em que foram definidas .
E com a automação adequada, isso é feito a cada logon, portanto, usar a maneira do Painel de controle possivelmente apenas atrapalharia as definições "aninhadas" para a sessão atual. Este método é provavelmente a melhor combinação .
Observe que, para evitar ter que fazer logoff para reler as variáveis, pode-se usar this , ou
refreshenv
.Detalhe do método 3 : A forma adequada de atingir o objetivo do OP (obter uma solução que funcione funcionalmente como se as variáveis fossem definidas via registro (ou Painel de Controle), mas evitando a ordem alfabética) é:
Usando um arquivo
.bat
(ou melhor, um.cmd
) , leia durante o logon (método 3), digamos,setvars.cmd
.Nesse arquivo, use
setx
para definir variáveis de ambiente no nível do registro (por exemplo,var2
). Isso não atualiza o ambiente local .Para ser capaz de usar definições de variáveis "aninhadas" que duram para a sessão do Windows (por exemplo,
var1
em termos do valor devar2
), é precisovar2
também ser definido no processo gerado porsetvars.cmd
. Conforme item 2 acima, isso não é realizado porsetx
. Para isso, adicionaria umaset
linha correspondente a cadasetx
linha. Com isso, obtém-se o mesmo ambiente no cartório e no processo local. Como alternativa, pode-se tentar usarREG query HKCU\Environment /V ...
encadeado com outros comandos (como usado, por exemplo, emrefreshenv
), mas não fiz isso. Se a maneira do Painel de controle for usada, ela pode atrapalhar as definições aninhadas que não seguem a ordem alfabética. Isso pode ser superado simplesmente executando novamentesetvars.cmd
.