Perché Windows non è in grado di gestire una variabile d'ambiente in Path?


44

Io e il mio collega abbiamo identiche workstation Dell con Windows XP Professional x64 edition installata.

La variabile d'ambiente My Path inizia con:

%JAVA_HOME%\bin;...

La variabile Path del mio collega include la stessa directory, specificata usando la stessa variabile d'ambiente, ma non è il primo elemento nel suo Path.

Se accedo alle proprietà di sistema -> variabili d'ambiente e cambio il valore della mia variabile JAVA_HOME, la versione di java trovata dalla riga di comando cambia come mi aspetto. Questo sta avviando una nuova finestra della console, per essere sicuri di raccogliere le modifiche.

Ma sulla macchina del mio collega no. Continua a trovare la sua versione precedente di Java fino a quando non visualizza la sua variabile Path e la salva (anche se non vi fa modifiche). (Ancora una volta, questo è quando si avvia una finestra console nuova di zecca.)

Osservo questa incoerenza su Windows ormai da circa 6 mesi e ne sono molto curioso. Abbiamo troppe versioni di Windows nel nostro ufficio, quindi raramente ho avuto la possibilità di vederlo accadere su due macchine che eseguono esattamente la stessa versione del sistema operativo, fino ad ora.

Cosa sta causando questo? Perché la sua macchina non rivaluta Path, usando il nuovo JAVA_HOME, quando lo fa il mio?

(È perché non è la prima cosa nel Path? Se sì, come potrebbe essere, e perché? Farei altri test per verificare, ma penso che ora sia stufo di farlo e vorrebbe tornare al lavoro .)


9
Per tutti voi ragazzi che votate per chiudere (3 al momento) ... se c'è un duplicato da qualche parte, un commento che mi indichi sicuramente sarebbe bello. Se non è un imbecille ... allora anche dirmi cosa pensi sia sbagliato in questa domanda sarebbe bello.
skiphoppy,

1
Forse perché è più una questione di sistema che di programmazione, sebbene abbia un impatto diretto sulla programmazione, ecco perché non voto per chiuderlo ... :)

9
Attenion close-nazis: Vorrei promuovere l'opinione secondo cui se una domanda era appropriata su Stack Overflow prima dell'arrivo di superuser.com e serverfault.com, oggi è ancora appropriato. Questa è una domanda di programmazione.
skiphoppy,

Vuoi dire che i programmatori sono solo utenti di Windows, che potrebbero avere questo problema? Stai zitto, programmatore-nazista! In secondo luogo, prima dell'arrivo di un sito di domande e risposte più appropriato, non hai avuto la possibilità di pubblicare domande qui. L'ospitalità della SO non deve essere un argomento per abusarne.
Val

Sto guardando questo in Windows 10 - la sostituzione delle variabili in PATH non è riuscita a funzionare in modo intermittente . Andare su Variabili d'ambiente e salvare (senza modifiche) e quindi aprire un nuovo prompt CMD ha risolto il problema.
Thomas W,

Risposte:


37

Il percorso è la concatenazione del percorso di sistema seguito dal percorso dell'utente. Inoltre, le variabili di ambiente di sistema potrebbero non contenere riferimenti a variabili di ambiente dell'utente e tali riferimenti non verranno espansi. Per ottenere il risultato desiderato, inserire il riferimento a% JAVA_HOME% nella variabile di ambiente utente PATH o creare tale variabile se non esiste già.

Forse un esempio semplificato lo renderà più chiaro. Supponiamo che l'ambiente SYSTEM sia

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

e l'ambiente dell'utente JSmith è

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

allora il percorso risultante sarebbe

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

come desiderato.


3
Il mio sistema aveva alcune variabili env dell'utente con lo stesso nome di alcune variabili env del sistema. Echoing PATH non li espande - dopo aver letto questo, ho rimosso le variabili utente duplicate mentre mi chiedevo se fossero state raccolte con precedenza (ma non potevo essere espanse). Questo ha funzionato per me - molte grazie. :)
Michael,

C'è un modo tramite Powershell per ottenere il PERCORSO originale non espanso? Speravo di aggiungere al mio PERCORSO preservando le variabili d'ambiente non espanse in esso.
CMCDragonkai,

Risolto con l'aiuto di un'altra domanda. Scrivi uno script PowerShell per gestire questo: gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai

16

Controlla nel registro di Windows con questa chiave:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

SE la variabile di ambiente deve essere espansa (qui:% JAVA_HOME%)

quindi la variabile deve essere impostata come valore REG_EXPAND_SZ .

Se si utilizza reg.exe dalla riga di comando per aggiungere / modificare i valori di registro, per impostazione predefinita digitare REG_SZ. Specificare il tipo REG_EXPAND_SZ utilizzando l' reg add /t REG_EXPAND_SZopzione.


sì ... questa è una di quelle impostazioni che mi sembra sempre di dimenticare ... fastidioso registro ;-)
Eddie B,

9

Esiste un problema definito con l'espansione delle variabili di ambiente all'interno della variabile PATH quando la variabile si espande in un percorso che contiene spazi.

Abbiamo creato le nostre variabili a livello di sistema come "OUR_ROOT = c: \ MyRoot" e quindi l'abbiamo usato nel PERCORSO di sistema come "PATH =;% OUR_ROOT% \ bin;" e che viene espanso correttamente in "PATH =; c: \ MyRoot \ bin;". Finora nessun problema.

Ma, su Windows 7 (32 bit), ho installato un prodotto e creato variabili di ambiente di sistema come questa:

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

e lo ha aggiunto alla variabile PATH di sistema:

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

Ma i valori PATH mostrati in CMD contenevano "% STUDIO_BIN%;" e non il percorso espanso. Anche il valore in Risorse del computer> Proprietà> Avanzate> Env.Vars non è stato ampliato. Ciò significava che non potevo eseguire programmi che richiedevano una DLL in quella directory.

Semplicemente cambiando STUDIO_BIN (tramite Risorse del computer> Proprietà> Avanzate ...> Env Vars) in un nome senza spazi incorporati:

STUDIO_BIN=C:\ProductName\bin

e quindi riavviando la finestra CMD, il PERCORSO è ora:

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

Un'altra soluzione è modificare sufficientemente la variabile di sistema che si sta utilizzando nel PERCORSO utilizzando la finestra di dialogo Risorse del computer> Proprietà> Avanzate ...> Variabili d'ambiente. Ho provato ad aggiungere un personaggio e rimuoverlo per fare una "modifica" e poi OK, ho avviato un nuovo prompt di CMD e il PERCORSO NON è stato espanso correttamente. Ho quindi provato a cancellare parte del percorso così com'era

STUDIO_BIN=C:\Program Files\Company Name

(omettendo "Nome prodotto 10.4") ed ecco, ed ecco, il prossimo prompt di CMD mostra PATH con STUDIO_BIN correttamente espanso!

Stranamente, se sono tornato indietro e ho aggiunto il "Nome prodotto 10.4" a STUDIO_BIN (compresi tutti gli spazi che erano originariamente lì prima che iniziassi a muck con esso) e PATH era ANCORA correttamente espanso.

Evidentemente con una modifica sufficiente al suo contenuto, la variabile PATH subisce qualche elaborazione aggiuntiva nella finestra di dialogo Variabili d'ambiente che le consente di funzionare. Elaborazione non eseguita quando la variabile è stata aggiunta dal programma di installazione del prodotto (che probabilmente ha appena modificato direttamente il PERCORSO nel registro).

Sono quasi sicuro che questo sia stato un problema anche con XP. È riemerso per me in Windows 7 mentre stavo mettendo insieme una nuova macchina di sviluppo. Apparentemente non è stato corretto da Microsoft.

Apparentemente anche le variabili definite da MS come% ProgramFiles% non si espandono correttamente nel PERCORSO.

Questa pagina fornisce una possibile risposta se si imposta PATH tramite la riga di comando o il file batch. (Racchiudere l'intero comando dopo SET tra virgolette.) Non so quale programma di installazione utilizzato dal prodotto che ho installato per impostare le variabili di ambiente, ma evidentemente ha fatto il giro di qualunque elaborazione sia necessaria per espandere correttamente i percorsi con spazi.

Quindi, per riassumere, puoi:

  • modificare i percorsi (e spostare tutti i file associati) in percorsi senza spazi, oppure

  • modifica le variabili che non riescono ad espandersi nella finestra di dialogo Variabili d'ambiente (modificandole abbastanza per farle elaborare correttamente - non sono sicuro di quanto sia abbastanza).


7

l'ho chiesto sui forum Microsoft nel marzo 2009 e non l'ho mai risolto:

Come usare% ProgramFiles% nella variabile d'ambiente Path? :


Sto cercando di aggiungere una cartella alla variabile d'ambiente Path del sistema.

voglio aggiungere % ProgramFiles% \ SysInternals

alla variabile di percorso esistente:

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

Quindi vado nel posto dove lo modifichi:

testo alternativo

E aggiungo la mia variabile al percorso:

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

Quindi, aprendo una nuova finestra del prompt dei comandi, la variabile di ambiente non viene sostituita con il valore effettivo:

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

Che puoi vedere nel seguente screenshot:

testo alternativo


Ma per rispondere alla tua domanda: non lo so. Sembra che non si possa fare.


5

ci sono due livelli di variabili d'ambiente, globale e utente. Se ha% Java_home% impostato come variabile di ambiente utente ma sta invece cambiando quella globale, non vedrà alcuna differenza.


2

Assicurarsi che non ci siano spazi nel PERCORSO quando si definiscono le proprie variabili di ambiente utente. ad es .: C: \ GNAT \ bin; C: \ GNAT \ include non funzionerà, a causa dello spazio tra ";" e "C: \ GNAT \ include".


2

Aggiungi le variabili di ambiente mentre sei loggato nella sessione / console usando MSTSC.

Riavvia il computer e scoprirai che le variabili di ambiente saranno persistite.

Sembra che ci sia una stranezza nell'O / S a seconda di come eri connesso alla macchina quando hai tentato di cambiare la variabile d'ambiente.


1

Potrebbe essere correlato alla funzione "espansione ritardata della variabile di ambiente" (o alla sua mancanza), o forse è possibile sfruttare questa funzione per avere sempre una soluzione corretta.

da un prompt cmd

set /? 

e leggi la sezione che descrive "espansione ritardata della variabile d'ambiente", che include un piccolo esempio da testare

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

Se non ottieni la linea dell'eco, questo potrebbe spiegarlo ...

Se, tuttavia, avvii il tuo cmd.exe con l'opzione / V, puoi usare "!" invece di "%", che cambia il comportamento

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

Per me (in esecuzione su XP), il 1 ° script non ha funzionato, ma la seconda versione ha funzionato (con cmd.exe / V)


1

Ho avuto lo stesso problema e so come risolverlo, è zoppo.

Modifica di nuovo il PERCORSO, ma non apportare modifiche e salva nuovamente il PERCORSO. Per qualche motivo, ciò fa rivalutare tutti i riferimenti alle variabili di ambiente nidificati.

Se non funziona, fallo ancora qualche volta, in qualche modo si risolve da solo.


1

Credo che Windows non riesca ad espandere una variabile in PERCORSO perché pensa a ciò che non ha ancora definito. Ritenere:

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

Questa ipotesi è conforme alla mia altra osservazione - l'aggiunta %ProgramFiles%\Somethingagli utenti PATH comporterà sempre l'espansione prevista di %ProgramFiles%, dato che è stata definita nell'ambiente della macchina al momento della notifica di modifica variabile (ordine di caricamento dovuto - MACCHINA e quindi UTENTE). Ma quando modifichi l'ambiente macchina, l'espansione variabile corretta si verifica solo al momento dell'avvio (in questo momento non ho idea di come e perché questo non accada su base regolare).


1

Devi considerare l'ordine in cui le variabili sono impostate al momento dell'accesso. Se si tenta di utilizzare una variabile prima che sia impostata, verrà visualizzata come stringa vuota.

Il PATH effettivo è la concatenazione della variabile PATH dell'utente seguita dalla variabile PATH globale.

Le variabili utente sono impostate prima delle variabili globali, quindi non è possibile utilizzare le variabili globali nella variabile PATH dell'utente. Inoltre, le variabili sono impostate in ordine alfabetico, quindi non è possibile utilizzare le variabili ordinate prima del PERCORSO.

(Questo vale almeno per Windows 7. Non l'ho provato su versioni più recenti.)


0

Forse stai sbagliando?

Ho provato con Windows XP Pro SP3 (32 bit). Ho un percorso con diverse occorrenze di %JAVA_HOME%(e %JAVAFX_HOME%, ecc.). Vado alla riga di comando, digito PATH, vedo le variabili espanse. Buono.

Cambio il valore di JAVA_HOME. Torna alla stessa finestra della riga di comando, PATHancora, stesso valore ... come previsto (per esperienza!).

Apro una nuova finestra della riga di comando PATH, digito, gotcha, vedo il nuovo valore.

Non sono sicuro di quale sia il meccanismo esatto lì, ma sembra che qualsiasi programma in esecuzione, incluso cmd.exe, acquisisca i valori delle variabili di ambiente all'inizio e non guardi indietro ... (anche se credo che un programma ben educato possa ascoltare le modifiche env, non troppo sicuro però).

Potrebbe essere visto come una funzionalità o un bug o un disturbo, ma è così che funziona. Ehi, almeno, a differenza delle volte Win9X, non è necessario riavviare il computer! E a differenza dei tempi di NT (IIRC), non è necessario disconnettersi e tornare indietro.

Perché l'incoerenza? I modi di Microsoft sono imperscrutabili ... :-P


Non è così Dopo la modifica stiamo testando in una nuova finestra di comando. Siamo consapevoli del fatto che la modifica dei valori di sistema non modifica i valori per i processi in esecuzione.
skiphoppy,

OK, quindi il 'forse' ... :-) E la mia spiegazione non copre l'incoerenza, ma potrebbe essere utile per alcuni principianti ...: -PI principalmente volevo sottolineare che l'espansione variabile funziona ovunque nel percorso. .. per alcuni sistemi! (tutti quelli che ho usato ... sempre a 32 bit).

0

Ho risolto l'impostazione delle variabili di ambiente in Sistema> Impostazioni avanzate> Variabili d'ambiente .

Ci sono due pannelli, variabili utente e globali (l'utente è il tuo nome utente di Windows) e le variabili di sistema sono variabili globali, quindi se imposti "Nuovo" dalle variabili utente, come JAVA_HOMEe inserisci il tuo percorso di seguito, imposterai le variabili anche se il tuo percorso globale avere file di programma all'interno della cartella.

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.