Чому Windows не може обробляти змінну середовища в Path?


44

У мене з колегою встановлені однакові робочі станції Dell із встановленим виданням Windows XP Professional x64.

Змінна середовища Мій шлях починається з:

%JAVA_HOME%\bin;...

Змінна Path мого колеги включає ту саму директорію, вказану за допомогою тієї ж змінної середовища, але це не перший елемент його шляху.

Якщо я отримаю доступ до системних властивостей -> змінних оточуючого середовища та змінюю значення моєї змінної JAVA_HOME, версія java, знайдена з командного рядка, змінюється, як я очікую. Це запускає абсолютно нове вікно консолі, щоб обов’язково взяти зміни.

Але на машині мого колеги це не так. Він продовжує знаходити свою попередню версію Java до тих пір, поки не відкриє свою змінну Path і не збереже її (навіть якщо не змінить її). (Знову ж таки, це стосується запуску абсолютно нового вікна консолі.)

Я спостерігав цю невідповідність у Windows близько 6 місяців і дуже цікаво про це. У нас в офісі занадто багато версій Windows, тому рідко мені доводилося бачити, що це відбувається на двох машинах із точно такою ж версією ОС, як і раніше.

Що це викликає? Чому його машина не переоцінює Шлях, використовуючи новий JAVA_HOME, коли мій?

(Це тому, що це не перше, що відбувається на Шлях? Якщо так, як це могло бути і чому? Я б зробив ще тести, щоб перевірити, але я думаю, він зараз цим набрид і хотів би повернутися до роботи .)


9
Для всіх, хто ви хочете проголосувати за закриття (3 зараз) ... якщо десь є дубль, коментар, який вказує мені на це, напевно було б добре. Якщо це не дурень ... то сказати мені, що ви вважаєте неправильним у цьому питанні, також було б непогано.
skiphoppy

1
Можливо тому, що це скоріше системне питання, ніж програмування, хоча воно має прямий вплив на програмування, тому я не голосую за його закриття ... :)

9
Увазі близьких нацистів: Я хотів би просувати думку про те, що якщо питання було доречним щодо переповнення стека перед тим, як надходити superuser.com та serverfault.com, це сьогодні доречно. Це питання програмування.
skiphoppy

Ви маєте на увазі, що програмісти - це лише користувачі Windows, які можуть мати цю проблему? Заткнись, програміст-нацист! По-друге, перед тим, як прийти більш відповідний веб-сайт із запитаннями, ви не мали можливості розміщувати питання тут. Гостинність SO не повинна бути аргументом для зловживань.
Валь

Я дивлюся на це в Windows 10 - заміна змінної на PATH не працювала з перервами . Перехід до змінних довкілля та збереження (без змін), а потім відкриття нового підказки CMD вирішив проблему.
Thomas W

Відповіді:


37

Ваш шлях - це з'єднання системного шляху, за яким слід шлях користувача. Крім того, змінні системного середовища можуть не містити посилань на змінні середовища користувача, і будь-які подібні посилання не будуть розширюватися. Щоб отримати бажаний результат, вставте посилання на% JAVA_HOME% у змінну PATH середовища користувача або створіть таку змінну, якщо вона ще не існує.

Можливо, спрощений приклад зробить це зрозумілішим. Припустимо, середовище SYSTEM є

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

а середовище користувача JSmith є

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

тоді отриманий шлях був би

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

за бажанням.


3
У моїй системі були деякі користувальницькі змінні env з тим самим іменем, що й деякі змінні env системи. Echoing PATH не розширив би їх - прочитавши це, я видалив повторювані користувацькі змінні, коли задумався, чи вони були підібрані з пріоритетом (але неможливо розширити). Це зараз працює для мене - велика подяка. :)
Майкл

Чи є спосіб через Powershell отримати оригінальний нерозширений ПАТ? Я сподівався приєднати до свого PATH, зберігаючи в ньому нерозширені змінні середовища.
CMCDragonkai

Вирішили це за допомогою допомоги іншого питання. Напишіть сценарій powerhell для вирішення цього питання: gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai

16

Перевірте в реєстрі Windows під цим ключем:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

ЯКЩО змінна середовище потребує розширення (тут:% JAVA_HOME%)

то змінна повинна бути встановлена ​​як значення REG_EXPAND_SZ .

Якщо ви використовуєте reg.exe через командний рядок для додавання / редагування значень реєстру, він за замовчуванням вводить REG_SZ. Вкажіть тип REG_EXPAND_SZ, скориставшись reg add /t REG_EXPAND_SZопцією.


так ... це одна з тих налаштувань, про які я, здається, завжди забуваю ... прискіпливий реєстр ;-)
Едді Б

9

Існує певна проблема з розширенням змінних середовища в змінній PATH, коли змінна розширюється на шлях, який містить пробіли.

Ми створили власні змінні на системному рівні, такі як "OUR_ROOT = c: \ MyRoot", а потім використовували її в системі PATH типу "PATH =;% OUR_ROOT% \ bin;" і це правильно розширюється до "PATH =; c: \ MyRoot \ bin;". Поки ніяких проблем.

Але в Windows 7 (32-розрядний) мені довелося встановити продукт і створити такі змінні системного середовища:

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

і він додав його до системної змінної PATH:

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

Але значення PATH, показані в CMD, містили "% STUDIO_BIN%;" а не розширений шлях. Значення в розділі "Мій комп'ютер"> "Властивості"> "Додатково"> "Env.Vars" також залишилося нерозширеним. Це означало, що я не міг запускати програми, для яких потрібна DLL у цьому каталозі.

Просто змінивши STUDIO_BIN (через Мій комп'ютер> Властивості> Додаткові ...> Env Vars) на ім'я без вбудованих пробілів:

STUDIO_BIN=C:\ProductName\bin

а потім перезапустіть вікно CMD, PATH зараз:

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

Ще одне рішення - достатньо відредагувати системну змінну, яку ви використовуєте в PATH, використовуючи діалогове вікно Мій комп'ютер> Властивості> Додаткові ...> Змінні середовища. Я спробував додати символ і видалити його, щоб внести «зміни», а потім OK'd out, запустив нову підказку CMD, і PATH НЕ було правильно розширено. Потім я спробував видалити частину шляху, щоб це було

STUDIO_BIN=C:\Program Files\Company Name

(опускаючи "Ім'я продукту 10.4") і ось, ось ось, наступний рядок CMD показав PATH зі STUDIO_BIN належним чином розширеним!

Як не дивно, якщо я повернувся назад і додав "Ім'я продукту 10.4" до STUDIO_BIN (включаючи всі пробіли, які були там спочатку, перш ніж я почав спілкуватися з ним), і PATH було ВІДПОВІДНО правильно розширено.

Очевидно при достатній зміні його змісту змінна PATH проходить деяку додаткову обробку в діалоговому вікні "Змінні середовища", що дозволяє їй працювати. Обробка цього не робиться, коли інсталятор продукту додав змінну (яка, ймовірно, просто змінила PATH безпосередньо в реєстрі).

Я майже впевнений, що це була проблема і з XP. Він просто з'явився для мене в Windows 7, коли я збирав нову розроблювальну машину. Мабуть, це Microsoft не виправила.

Мабуть, навіть визначені MS змінні, такі як% ProgramFiles%, не розширяться правильно в PATH.

Ця сторінка дає можливу відповідь, якщо ви встановлюєте PATH через командний рядок або пакетний файл. (Укладіть всю команду після SET у лапки.) Я не знаю, який інсталятор продукту, який я встановив, використовувався для встановлення змінних середовища, але він, очевидно, обійшов будь-яку обробку, необхідну для правильного розширення шляхів з пробілами.

Отже, підводячи підсумок, ви можете:

  • змінити контури (і перемістити всі пов’язані файли) на шляхи без пробілів, або

  • відредагуйте змінні, які не вдається розширити в діалоговому вікні "Змінні середовища" (змінивши їх досить, щоб вони могли правильно обробити - я не впевнений, наскільки це достатньо).


7

Я запитав це на форумах Microsoft у березні 2009 року, і жодного разу не вирішив:

Як використовувати% ProgramFiles% у змінній середовища Path? :


Я намагаюся додати папку до змінної середовища Path системи.

я хочу додати % ProgramFiles% \ SysInternals

до існуючої змінної шляху:

C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Bin; % SystemRoot% \ system32; % SystemRoot% ;% SystemRoot % \ System32 \ Wbem; C: \ програмні файли \ Microsoft SQL Server \ 80 \ інструменти \ BINN; C: \ програмні файли \ Microsoft SQL сервер \ 80 \ інструменти \ binn \; c: \ програмні файли \ Microsoft SQL Server \ 90 \ Інструменти \ binn \; C: \ Програмні файли \ Microsoft SQL Server \ 90 \ DTS \ Binn \; C: \ Програмні файли \ Microsoft SQL Server \ 90 \ Інструменти \ Binn \ VSShell \ Common7 \ IDE \; C: \ Файли програм \ Microsoft Visual Studio 8 \ Common7 \ IDE \ PrivateAssemblies \;% SYSTEMROOT % \ System32 \ WindowsPowerShell \ v1.0 \

Тож я заходжу на місце, де ви його редагуєте:

alt текст

І я додаю свою змінну до шляху:

% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl; (сніп)

Потім, відкривши нове вікно командної строки, змінна середовища не замінюється фактичним значенням:

Шлях =% ProgramFiles % \ SysInternals; C: \ PROGRA ~ 1 \ Borland \ Delphi5 \ Projects \ Bpl (snip)>

Що ви можете побачити на наступному скріншоті:

alt текст


Але щоб відповісти на ваше запитання: я не знаю. Здається, це неможливо зробити.


5

є два рівні змінних середовища, глобальний та користувальницький. Якщо у нього% Java_home% встановлено як змінну середовища користувача, але замість цього він змінює глобальний, він не побачить різниці.


2

Переконайтеся, що в PATH немає пробілів, коли ви визначаєте власні змінні середовища користувача. наприклад: C: \ GNAT \ bin; C: \ GNAT \ включають звичну роботу через пробіл між ";" та "C: \ GNAT \ включити".


2

Додайте змінні середовища під час реєстрації на сесії / консолі за допомогою MSTSC.

Перезавантажте машину, і ви побачите, що ваші змінні середовища збережуться.

Здається, що в O / S є примха залежно від того, як ви були підключені до машини при спробі зміни змінної середовища.


1

Це може бути пов’язано з функцією "затримка розширення змінної середовища" (або її відсутність), або, можливо, ви можете скористатися цією функцією, щоб завжди мати правильне рішення.

з підказки cmd

set /? 

і прочитати розділ, що описує "затримку розширення змінної середовища", який включає невеликий приклад для тестування

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

Якщо ви не отримаєте лінію ехо, то це може пояснити це ...

Якщо ви запустили свій cmd.exe з / V опцією, ви можете використовувати "!" замість "%", що змінює поведінку

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

Для мене (працює на XP) 1-й скрипт не працював, але другий варіант зробив (з cmd.exe / V)


1

У мене була така ж проблема, і я знаю, як її виправити, її кульгавість.

Просто відредагуйте свій PATH ще раз, але не вносити жодних змін і знову збережіть PATH. Чомусь це призводить до повторної оцінки всіх вкладених посилань змінної середовища.

Якщо це не працює, зробіть це ще кілька разів, інакше це просто вийде.


1

Я вірю в те, що Windows не в змозі розширити змінну в PATH, тому що думає те, що ще не визначено. Поміркуйте:

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

Ця гіпотеза відповідає моєму іншому спостереженню - додавання %ProgramFiles%\Somethingдо користувачів PATH завжди призведе до очікуваного розширення %ProgramFiles%, враховуючи, що воно було визначене в машинному середовищі під час повідомлення про змінні зміни (належне замовлення на завантаження - МАШИНА, а потім ПОТРІБНИК). Але коли ви модифікуєте машинне середовище, правильне змінне розширення відбувається лише під час завантаження (зараз я не маю уявлення, як і чому це не відбувається регулярно).


1

Ви повинні врахувати порядок, в якому змінні встановлюються при вході в систему. Якщо ви спробуєте використати змінну до її встановлення, вона вийде як порожній рядок.

Ефективний PATH - це конкатенація змінної PATH користувача з наступною глобальною змінною PATH.

Користувацькі змінні встановлюються перед глобальними змінними, тому ви не можете використовувати глобальні змінні у вашій змінній PATH користувача. Крім того, змінні встановлюються в алфавітному порядку, тому ви не можете використовувати змінні, які сортуються перед PATH.

(Це стосується принаймні Windows 7. Я не перевіряв це на нових версіях.)


0

Можливо, ви робите це неправильно?

Я спробував з Windows XP Pro SP3 (32-бітний). У мене є шлях з кількома входженнями %JAVA_HOME%%JAVAFX_HOME%тощо). Я переходжу до командного рядка, набираю PATH, бачу, що змінні розширюються. Добре.

Я змінюю значення JAVA_HOME. Повернення до того ж вікна командного рядка, PATHзнову ж таки, таке ж значення ... як і очікувалося (за досвідом!).

Відкриваю нове вікно командного рядка PATH, набираю, gotcha, бачу нове значення.

Не впевнений, який саме там механізм, але здається, що будь-яка запущена програма, включаючи cmd.exe, фіксує значення змінних середовища в момент запуску, і не озирається назад ... (хоча я вважаю, що хороша програма, яка вела себе, може слухати зміни ENV, хоча не надто впевнений).

Це може розглядатися як особливість або помилка чи роздратування, але це саме так. Ей, принаймні, на відміну від Win9X разів, нам не доведеться перезавантажувати комп’ютер! І на відміну від NT разів (IIRC), вам не потрібно виходити та повертатися назад.

Чому непослідовність? Шляхи Microsoft непереборні ... :-P


Це не все. Після зміни ми тестуємо в новому вікні команди. Ми усвідомлюємо той факт, що зміна системних значень не змінює значення для запущених процесів.
skiphoppy

Гаразд, отже, "можливо" ... :-) І моє пояснення не охоплює непослідовність, але може бути корисним для новачків ...: - Я, головним чином, хотів зазначити, що розширення змінної працює скрізь на шляху. .. для деяких систем! (всі ті, якими я користувався ... завжди 32-бітний).

0

Я вирішив встановити змінні середовища в Системі> Додаткові параметри> Змінні середовища .

Існують дві панелі, користувальницькі та глобальні змінні (користувач - ваше ім’я користувача Windows) та системні змінні - глобальні змінні, тож якщо ви встановите "Нове" з користувацьких змінних, таких як JAVA_HOMEі поставите шлях нижче, ви встановите змінні, навіть якщо ваш глобальний шлях мати програмні файли всередині папки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.