Dlaczego system Windows nie może obsłużyć zmiennej środowiskowej w ścieżce?

44

Mój kolega i ja mamy identyczne stacje robocze Dell z zainstalowanym systemem Windows XP Professional x64.

Zmienna środowiskowa My Path zaczyna się od:

%JAVA_HOME%\bin;...

Zmienna Path mojego kolegi zawiera ten sam katalog, określony przy użyciu tej samej zmiennej środowiskowej, ale nie jest to pierwszy element w jego Path.

Jeśli uzyskam dostęp do właściwości systemu -> zmiennych środowiskowych i zmienię wartość mojej zmiennej JAVA_HOME, wersja java znaleziona w wierszu poleceń zmieni się zgodnie z oczekiwaniami. To uruchamia zupełnie nowe okno konsoli, aby pamiętać o zmianach.

Ale na maszynie mojego kolegi tak nie jest. Nadal znajduje swoją poprzednią wersję Javy, dopóki nie wyświetli swojej zmiennej Path i nie zapisze jej (nawet jeśli nie dokona żadnych zmian). (Znowu dzieje się tak podczas uruchamiania nowego okna konsoli).

Obserwuję tę niespójność w systemie Windows od około 6 miesięcy i jestem bardzo ciekawy. W naszym biurze mamy zbyt wiele wersji systemu Windows, więc do tej pory rzadko miałem okazję zobaczyć, jak to się dzieje na dwóch komputerach z taką samą wersją systemu operacyjnego.

Co to powoduje? Dlaczego jego maszyna nie dokonuje ponownej oceny Path, używając nowego JAVA_HOME, kiedy robi to mój?

(Czy to dlatego, że nie jest to pierwsza rzecz na Ścieżce? Jeśli tak, jak to możliwe i dlaczego? Zrobiłbym więcej testów, aby to sprawdzić, ale myślę, że ma już tego dość i chciałby wrócić do pracy .)

skiphoppy
źródło
9
Dla wszystkich, którzy głosują na zamknięcie (w tej chwili 3) ... jeśli gdzieś jest duplikat, komentarz wskazujący mnie na pewno byłby miły. Jeśli to nie jest dupek ... powiedzenie mi, co uważasz za niewłaściwe w tym pytaniu, również byłoby miłe.
skiphoppy
1
Być może dlatego, że jest to raczej pytanie systemowe niż programowe, chociaż ma bezpośredni wpływ na programowanie, dlatego nie głosuję, aby je zamknąć ... :)
9
Często bliscy naziści: Chciałbym promować pogląd, że jeśli pytanie dotyczące przepełnienia stosu było odpowiednie przed pojawieniem się superuser.com i serverfault.com, jest ono nadal aktualne. To jest pytanie programistyczne.
skiphoppy
Czy masz na myśli, że programiści są tylko użytkownikami systemu Windows, którzy mogą mieć ten problem? Zamknij się, programista-naziście! Po drugie, zanim pojawiła się bardziej odpowiednia strona z pytaniami i odpowiedziami, nie miałeś możliwości opublikowania tutaj pytania. Gościnność SO nie może być argumentem za nadużyciami.
Val
Patrzę na to w Windows 10 - podstawienie zmiennych do PATH nie działało sporadycznie . Przejście do zmiennych środowiskowych i zapisywanie (bez zmian), a następnie otwarcie nowego monitu CMD rozwiązało problem.
Thomas W

Odpowiedzi:

37

Twoja ścieżka to konkatenacja ścieżki systemowej, po której następuje ścieżka użytkownika. Ponadto systemowe zmienne środowiskowe nie mogą zawierać odniesień do zmiennych środowiskowych użytkownika, a wszelkie takie odniesienia nie zostaną rozwinięte. Aby uzyskać pożądany wynik, wstaw odwołanie do% JAVA_HOME% w zmiennej środowiskowej użytkownika PATH lub utwórz taką zmienną, jeśli jeszcze nie istnieje.

Być może uproszczony przykład to wyjaśni. Załóżmy, że środowisko SYSTEM jest

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

a środowisko użytkownika JSmith to

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

wtedy powstałaby ścieżka

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

zgodnie z życzeniem.

JPaget
źródło
3
Mój system miał pewne zmienne env użytkownika o takiej samej nazwie jak niektóre systemowe zmienne env. Echoing PATH nie rozwinąłby ich - po przeczytaniu tego usunąłem zduplikowane zmienne użytkownika, zastanawiając się, czy były one wybierane priorytetowo (ale nie można ich rozwinąć). To mi się teraz udało - wielkie dzięki. :)
Michael
Czy istnieje sposób za pomocą Powershell, aby uzyskać oryginalną nierozwiniętą ŚCIEŻKĘ? Miałem nadzieję dołączyć do mojej PATH zachowując w niej nierozwinięte zmienne środowiskowe.
CMCDragonkai
Rozwiązano to przy pomocy innego pytania. Napisz skrypt PowerShell, aby to obsłużyć: gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai
16

Sprawdź w rejestrze systemu Windows pod tym kluczem:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

JEŚLI zmienna środowiskowa musi zostać rozwinięta (tutaj:% JAVA_HOME%)

następnie zmienną należy ustawić jako wartość REG_EXPAND_SZ .

Jeśli używasz reg.exe za pomocą wiersza polecenia do dodawania / edycji wartości rejestru, domyślnie wpisuje REG_SZ. Określ typ REG_EXPAND_SZ, używając reg add /t REG_EXPAND_SZopcji.

klimenol
źródło
tak ... to jest jedno z tych ustawień, o których zawsze zdaje się zapominać ... nieznośny rejestr ;-)
Eddie B
9

Istnieje wyraźny problem z rozszerzaniem zmiennych środowiskowych w zmiennej PATH, gdy zmienna rozwija się do ścieżki zawierającej spacje.

Stworzyliśmy własne zmienne na poziomie systemu, takie jak „OUR_ROOT = c: \ MyRoot”, a następnie wykorzystaliśmy je w ŚCIEŻCE systemu, np. „PATH =;% OUR_ROOT% \ bin;” i to jest poprawnie rozwijane do „PATH =; c: \ MyRoot \ bin;”. Jak dotąd nie ma problemu.

Ale w systemie Windows 7 (32-bitowym) sam zainstalowałem produkt i utworzyłem systemowe zmienne środowiskowe w następujący sposób:

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

i dodał ją do zmiennej systemowej PATH:

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

Ale wartości PATH pokazane w CMD zawierały „% STUDIO_BIN%;” a nie rozwinięta ścieżka. Wartość w Mój komputer> Właściwości> Zaawansowane> Różnice środowiskowe również pozostała nierozwinięta. Oznaczało to, że nie mogłem uruchamiać programów wymagających biblioteki DLL w tym katalogu.

Po prostu zmieniając STUDIO_BIN (przez Mój komputer> Właściwości> Zaawansowane ...> Zmienne środowiskowe) na nazwę bez osadzonych spacji:

STUDIO_BIN=C:\ProductName\bin

a następnie ponownie uruchamiając okno CMD, ŚCIEŻKA jest teraz:

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

Innym rozwiązaniem jest wystarczająca edycja zmiennej systemowej używanej w ŚCIEŻCE za pomocą okna dialogowego Mój komputer> Właściwości> Zaawansowane ...> Zmienne środowiskowe. Próbowałem dodać znak i usunąć go, aby dokonać „zmiany”, a następnie OK, uruchomiłem nowy monit CMD, a ŚCIEŻKA NIE została poprawnie rozwinięta. Następnie spróbowałem usunąć część ścieżki, tak było

STUDIO_BIN=C:\Program Files\Company Name

(pomijając „Nazwę produktu 10.4”) i lo, a oto następny monit CMD pokazał ŚCIEŻKĘ z STUDIO_BIN odpowiednio rozwiniętym!

O dziwo, gdybym wrócił i dodał „Nazwę produktu 10.4” do STUDIO_BIN (w tym wszystkie spacje, które pierwotnie tam były, zanim zacząłem z nim wycinać), a ŚCIEŻKA JEST W dalszym ciągu poprawnie rozwinięta.

Najwyraźniej przy wystarczającej zmianie zawartości zmienna PATH jest poddawana dodatkowemu przetwarzaniu w oknie dialogowym Zmienne środowiskowe, które umożliwia jej działanie. Przetwarzanie, które nie jest wykonywane, gdy zmienna została dodana przez instalator produktu (który prawdopodobnie właśnie zmodyfikował PATH bezpośrednio w rejestrze).

Jestem prawie pewien, że to był problem również z XP. Właśnie pojawiło się dla mnie w systemie Windows 7, gdy tworzyłem nową maszynę programistyczną. Najwyraźniej nie zostało to naprawione przez Microsoft.

Najwyraźniej nawet zmienne zdefiniowane przez MS, takie jak% ProgramFiles%, nie rozwijają się poprawnie w ŚCIEŻCE.

Ta strona zawiera możliwą odpowiedź, jeśli ustawiasz PATH za pomocą wiersza polecenia lub pliku wsadowego. (Całą komendę po SET umieść w cudzysłowie). Nie wiem, jakiego instalatora użyłem produktu, który zainstalowałem, aby ustawić zmienne środowiskowe, ale najwyraźniej obejrzał to, co jest potrzebne do prawidłowego rozszerzenia ścieżek spacjami.

Podsumowując, możesz:

  • zmień ścieżki (i przenieś wszystkie powiązane pliki) na ścieżki bez spacji lub

  • edytuj zmienne, które nie rozwijają się w oknie dialogowym Zmienne środowiskowe (zmieniając je na tyle, aby umożliwić ich prawidłowe przetwarzanie - nie jestem pewien, ile wystarczy).

RobDavenport
źródło
7

zapytałem o to na forach Microsoft w marcu 2009 roku i nigdy nie udało mi się rozwiązać:

Jak używać% ProgramFiles% w zmiennej środowiskowej Path? :


Próbuję dodać folder do systemowej zmiennej środowiskowej Path.

Chcę dodać % ProgramFiles% \ SysInternals

do istniejącej zmiennej ścieżki:

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

Więc idę w miejsce, w którym je edytujesz:

alternatywny tekst

I dodaję moją zmienną do ścieżki:

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

Następnie otwierając nowe okno wiersza poleceń zmienna środowiskowa nie jest zastępowana jej rzeczywistą wartością:

Ścieżka =% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl (snip)>

Które można zobaczyć na poniższym zrzucie ekranu:

alternatywny tekst


Ale żeby odpowiedzieć na twoje pytanie: nie wiem. Wydaje się, że nie da się tego zrobić.

Ian Boyd
źródło
5

istnieją dwa poziomy zmiennych środowiskowych: globalny i użytkownika. Jeśli ma% Java_home% ustawiony jako zmienna środowiskowa użytkownika, ale zamiast tego zmienia zmienną globalną, nie zobaczy żadnej różnicy.

Sekhat
źródło
2

Upewnij się, że w PATH nie ma spacji podczas definiowania własnych zmiennych środowiskowych użytkownika. np .: C: \ GNAT \ bin; C: \ GNAT \ include nie będzie działać z powodu odstępu między „;” i „C: \ GNAT \ include”.

Nij
źródło
2

Dodaj zmienne środowiskowe podczas logowania do sesji / console przy użyciu MSTSC.

Uruchom ponownie komputer, a przekonasz się, że zmienne środowiskowe zostaną zachowane.

Wygląda na to, że w O / S występuje dziwactwo w zależności od tego, jak byłeś podłączony do komputera, gdy próbowałeś zmienić zmienną środowiskową.

Justin
źródło
1

Może to być związane z funkcją „opóźnionego rozszerzenia zmiennej środowiskowej” (lub jej brak), a może możesz skorzystać z tej funkcji, aby zawsze mieć właściwe rozwiązanie.

z wiersza polecenia cmd

set /? 

i przeczytaj sekcję opisującą „opóźnione rozszerzenie zmiennej środowiskowej”, która zawiera mały przykład do przetestowania

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

Jeśli nie otrzymasz linii echa, to może to wyjaśnić ...

Jeśli jednak uruchomisz program cmd.exe z opcją / V, możesz użyć „!” zamiast „%”, co zmienia zachowanie

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

Dla mnie (działający na XP) pierwszy skrypt nie działał, ale druga wersja działała (z cmd.exe / V)

libjack
źródło
1

Miałem ten sam problem i wiem, jak go naprawić, jego kulawizna.

Po prostu edytuj ŚCIEŻKĘ ponownie, ale nie wprowadzaj żadnych zmian i ponownie zapisz ŚCIEŻKĘ. Z jakiegoś powodu powoduje to, że wszystkie odwołania do zagnieżdżonych zmiennych środowiskowych są ponownie oceniane.

Jeśli to nie zadziała, zrób to jeszcze kilka razy, jakoś to po prostu zadziała.

BAP
źródło
1

Wierzę, że system Windows nie rozwija zmiennej w zmiennej PATH, ponieważ uważa to, czego jeszcze nie zdefiniował. Rozważać:

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

Hipoteza ta jest zgodna z moją inną obserwacją - dodanie %ProgramFiles%\Somethingdo użytkowników PATH zawsze spowoduje spodziewane rozszerzenie %ProgramFiles%, o ile zostało zdefiniowane w środowisku maszyny w momencie powiadomienia o zmianie zmiennej (należna kolejność ładowania - MASZYNA, a następnie UŻYTKOWNIK). Ale kiedy modyfikujesz środowisko maszynowe, poprawne rozszerzanie zmiennych zachodzi tylko w czasie uruchamiania (w tej chwili nie mam pojęcia, jak i dlaczego nie dzieje się to regularnie).

użytkownik539484
źródło
1

Musisz wziąć pod uwagę kolejność ustawiania zmiennych podczas logowania. Jeśli spróbujesz użyć zmiennej przed jej ustawieniem, wyjdzie ona jako pusty ciąg.

Efektywna PATH to konkatenacja zmiennej PATH użytkownika, po której następuje globalna zmienna PATH.

Zmienne użytkownika są ustawione przed zmiennymi globalnymi, więc nie można używać zmiennych globalnych w zmiennej użytkownika PATH. Dodatkowo zmienne są ustawione w kolejności alfabetycznej, więc nie można używać zmiennych sortujących przed PATH.

(Dotyczy to przynajmniej systemu Windows 7. Nie testowałem tego na nowszych wersjach).

cbarrick
źródło
0

Być może robisz to źle?

Próbowałem z Windows XP Pro SP3 (32-bitowy). Mam ścieżkę z kilkoma wystąpieniami %JAVA_HOME%(i %JAVAFX_HOME%itp.). Idę do wiersza poleceń, wpisz PATH, widzę, że zmienne są rozwinięte. Dobry.

Zmieniam wartość JAVA_HOME. Wróć do tego samego okna wiersza poleceń, PATHponownie, ta sama wartość ... zgodnie z oczekiwaniami (z doświadczenia!).

Otwieram nowe okno wiersza poleceń, wpisz PATH, gotcha, widzę nową wartość.

Nie jestem pewien, jaki jest tam dokładny mechanizm, ale wydaje się, że każdy uruchomiony program, w tym cmd.exe, przechwytuje wartości zmiennych środowiskowych w czasie uruchamiania i nie ogląda się wstecz ... (chociaż uważam, że dobry program może nasłuchuj zmian env, choć nie jestem tego pewien).

Może to być postrzegane jako funkcja lub błąd lub irytacja, ale tak to działa. Hej, przynajmniej w przeciwieństwie do Win9X razy, nie musimy restartować komputera! I w przeciwieństwie do czasów NT (IIRC), nie musisz się wylogowywać i cofać.

Dlaczego niespójność? Sposoby Microsoftu są nieodgadnione ... :-P

PhiLho
źródło
To nie jest to. Po zmianie testujemy w nowym oknie poleceń. Wiemy, że zmiana wartości systemowych nie zmienia wartości dla uruchomionych procesów.
skiphoppy
OK, stąd „być może” ... :-) A moje wyjaśnienie nie obejmuje niekonsekwencji, ale może być przydatne dla początkujących ...: -PI chciałem przede wszystkim podkreślić, że ekspansja zmiennych działa wszędzie na ścieżce. .. dla niektórych systemów! (wszystkie te, których użyłem ... zawsze 32-bitowe).
0

Rozwiązałem ustawianie zmiennych środowiskowych w System> Ustawienia zaawansowane> Zmienne środowiskowe .

Istnieją dwa panele, zmienne użytkownika i globalne (użytkownik to nazwa użytkownika systemu Windows), a zmienne systemowe to zmienne globalne, więc jeśli ustawisz „Nowy” ze zmiennych użytkownika, takich jak JAVA_HOMEi umieścisz swoją ścieżkę poniżej, ustawisz zmienne, nawet jeśli twoja globalna ścieżka mieć pliki programu w folderze.

thunder_nemesis
źródło