- Сообщения
- 7,981
- Реакции
- 6,756
Дело о заблокированной переменной окружения %PATH%.
Автор: DragokasКак-то раз мне потребовалось отсканировать документ, но при попытке открыть интерфейс сканера появилась ошибка:
Согласно одному из советов на официальном сайте было предложено добавить папку с библиотеками сканера в переменную PATH, что я и сделал по своей же инструкции:
- Скопировал в буфер обмена нужный путь (у меня это «C:\Windows\twain_32\CNQL25», без кавычек)
- Открыл оснастку «Система» быстрой комбинацией Win + R
- Нажал слева «Дополнительные параметры» => «Переменные среды»
- В группе «Системные переменные» нашел переменную PATH, «Изменить»
- Поставил курсор в конец строки с полем «Значение переменной» и убедился, что в конце строки есть знак «точка с запятой»
- И нажал «Вставить из буфера» по ПКМ.
Но ничего не вставилось, а в колонках раздался радостный звук «Дзыньк» =)))
Первая мысль – в буфер обмена ничего не скопировалось (хотя в этом случае пункт «Вставить» должен был быть серым).
Ну да ладно, гадать не буду, и решил просто вручную набрать путь с клавиатуры.
Но не тут-то было.
В ответ всё те же радостные звуки «Дзыньк-дзыньк».
Неисправна клавиатура?
Да нет же, проверил в блокноте, всё нормально набирается.
Что же делать?
1. Способ дилетанта
PATH можно заменить несколькими способами, и поскольку мне нужно было срочно отсканировать документ, мне было все равно как это сделать, и не было времени разбираться с ошибкой.
PATH – это особая переменная, которая собирается из двух параметров PATH в ключах реестра:
Учитывая, что у меня на полочке лежит недописанная статья о переменных окружения, было нетрудно «вспомнить» этот путь, перейти туда, открыв «Редактор реестра» (Win + R, regedit), и отредактировать значение параметра PATH.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
HKEY_CURRENT_USER\Environment (по-умолчанию, здесь параметра PATH нет).
OK, перезагрузка, и ошибка со сканером пропала.
Отступление от темы статьи:
… хотя появилась другая ошибка, что якобы TWAIN используется другим устройством.
Дальше была переустановка драйвера сканера с удалением уст-ва через «Панель управления». Но это тоже не помогло. В общем, в итоге я всё-таки отсканировал документ, подцепив USB-сканер через виртуальную машину с Windows XP непосредственно в момент установки драйвера (кстати, виртуалка с Win7, почему-то отказалась его увидеть).
2. Способ рядового исследователя
И вот, наконец, появилось время разобраться, что же происходит с PATH.
Новая мысль – заблокированы права (политики? список контроля доступа (DACL) ? ).
О политиках я не слышал, чтобы была такая, контролирующая PATH (но не исключаю).
А на счёт списка прав – они назначаются только на весь ключ реестра, а не на конкретный параметр (в нашем случае переменную). Т.е., если заблокирована PATH, то тоже самое должно происходить и со всеми соседними переменными.
Проверим?
Эксперимент.
Возьму первую попавшуюся – переменную «OS».
Пробую – и бац, в оснастке «Переменные среды» её значение легко поменялось.
Так-то. Давайте подойдём с другой стороны:
а что на счёт консоли?
Командная строка CMD (Win + R, cmd) позволяет также менять значение PATH, но это работает только в границах сессии консоли, а не на всю систему.
Там даже есть отдельная внутренняя команда Path. Но мы обойдёмся без неё.
Добавим для теста наш путь командой:
CMD/BATCH:
set Path=%Path%;C:\Windows\twain_32\CNQL25
Получили «Отказано в доступе».
Любопытно.
Всё таки: проблемы в правах?
А что если просто распечатать содержимое?
Вот так новость. Я её даже не могу распечатать!
Попробуем с правами администратора?
Именем святого Админа, запускаем командную строку:
Нет, всё же, не везёт нам.
Может дело просто в каких-то спецсимволах в путях? Ком. строка очень не любит всякие птички ^, скобки и прочее.
Давайте заключим содержимое в кавычки:
Вуаля
![Smile :) :)](https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/1f642.png)
И даже работает присвоение:
CMD/BATCH:
set "Path=%Path%;C:\Windows\twain_32\CNQL25"
Хорошо. Но в чём именно проблема?
Я скопировал в блокнот всё значение (взял из реестра).
И методом половинного деления начал подставлять эту строку в echo.
В итоге выяснилось, что где-то в средину пути попала такая штука:
Символ перенаправления строки в файл >.
В итоге, вместо того, чтобы распечатать строку на экран консоли, она пыталась вывести её в файл C:\Windows\System32;C:\Windows;C:\Wi… не являющийся корректным именем. Из-за чего и возникала ошибка «Отказано в доступе»
![Smile :) :)](https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/1f642.png)
А что же на счёт системы?
> - это недопустимый символ для пути. Получается, всё это время система «глючила» из-за него?
Открыв редактор реестра, я удалил знак > из параметра PATH.
(заодно заметив, что у меня 2 раза повторяются все пути, но пока решил это не трогать).
ОК, ещё раз захожу в оснастку «Система» в «переменные окружения», пытаюсь изменить значение PATH, и … снова не получается.
Но тут всё понятно:
Известно, что каждый процесс хранит в памяти блок переменных окружения, и не изменяет его, пока система не отправит специальное сообщение. И даже в этом случае процесс не обязан обновить переменные.
Так что мы просто перезапустим процесс explorer, который отвечает за загрузку окон оснасток (напомню, это можно сделать через Ctrl + Shift + ПКМ по окну в меню «Пуск»).
Или, что более надёжно, перезагрузим всю систему.
Вот уже появились ярлычки. Захожу, проверяю, и …
Каково было удивление, но ничего не сработало. Символы опять не печатаются в поле «Значение переменной». ))))
Но не отчаиваемся. Остался один очевидный факт:
1) Два раза дублируются пути
2) Строка с содержимым Path какая-то уж слишком длинная
3) Заметил, что в поле «Значение переменной» хоть и нельзя печатать, но можно удалять символы.
Итак, ограничение по длине?
Но, какого рода лимит?
Может, предел для длины значения параметра реестра?
Открываем базу знаний Micosoft: Registry Elements Size Limits.
Там говорят:
А наша строка = 2271 символов.Value name
16,383 characters
Windows 2000: 260 ANSI characters or 16,383 Unicode characters.
Пишут, что в Win2k был жесткий лимит – в 260, но это только для ANSI-версий API-функций, а внутренне – строки хранятся в реестре все равно в Unicode. Точнее, в смешанном виде ANSI + Unicode (механизм оптимизации, детальнее о котором писал Руссинович в «Windows Internals»). Да и у меня под руками Windows 7, так что не вариант.
Эксперимент.
Поскольку оснастка даёт нам право удалять символы, а давайте так и сделаем.
Будем удалять их до тех пор, пока текстовое поле не позволит нам вводить новые символы.
И… ура, сработало
![Smile :) :)](https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/1f642.png)
После нескольких десятков удалённых, нам позволили наконец-то вводить новые символы (не пришлось даже нажимать кнопку «ОК»).
Давайте же замерим, сколько получилось в итоге максимальное число символов.
Мой любимый AkelPad показывает что их – 2047.
Вот как. И что же за магическое число 2047 ?
Спросим у великого гуру – Google: «Path limit 2047»
Первая же ссылка ведёт на довольно любопытную статью от Karthiyayini C. (из Intel): Limitation to the length of the System PATH variable.
В ней даётся таблица с симптомами «переполнения» переменной PATH, когда её длина >= 2048 символов:
[TABLE=no-full-width-collapse][TR][TH]Размер PATH[/TH]
[TH]Windows XP, Windows Server 2003[/TH]
[TH]Windows 7, Windows 8, Windows Server 2008[/TH][/TR]
[TR][TD]
< 2048 байтов
[/TD]
[TD]
Всё работает прекрасно
[/TD]
[TD]
Всё работает прекрасно
[/TD][/TR]
[TR][TD]
>= 2048 и < 4096 байтов
[/TD]
[TD]
1. PATH пустой в командной строке (echo %PATH%)
[/TD]
[TD]
1. PATH пустой в командной строке (echo %PATH%)
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
2. Нельзя запустить приложение из-под командной строки без указания полного пути (notepad.exe)
[/TD]
[TD]
2. Нельзя запустить приложение из-под командной строки без указания полного пути (notepad.exe)
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
3. Можно запустить приложение из-под командной строки, указав полный путь (c:\windows\system32\notepad.exe)
[/TD]
[TD]
3. Можно запустить приложение из-под командной строки, указав полный путь (c:\windows\system32\notepad.exe)
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
4. Windows Explorer работает прекрасно
[/TD]
[TD]
4. Windows Explorer работает прекрасно
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
5. Можно запустить “Панель Управления\Система\Дополнительные параметры системы”
[/TD]
[TD]
5. Невозможно запустить “Панель Управления\Система\Дополнительные параметры системы”
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
6. Можно получить “Дополнительные параметры системы” из-под командной строки %WinDir%\System32\SystemPropertiesAdvanced.exe
[/TD]
[TD]
6. Можно получить “Дополнительные параметры системы” из-под командной строки %WinDir%\System32\SystemPropertiesAdvanced.exe
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
7. “Дополнительные параметры системы” могут отобразить все переменные окружения, включая PATH
[/TD]
[TD]
7. Дополнительные параметры системы” могут отобразить все переменные окружения, включая PATH
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
8. После перезапуска системы, PATH больше не пустая, но обрезана до 2048 символов
[/TD]
[TD]
8. После перезапуска системы PATH больше не пустая и ведёт себя нормально
[/TD][/TR]
[TR][TD]
>= 4096 байтов
[/TD]
[TD]
пп. 1, 2, 3, 4, 5 и 6 так же, как выше
[/TD]
[TD]
пп. 1, 2, 3, 4, 5 и 6 так же, как выше
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
“Дополнительные параметры системы” не отображают большинство переменных окружения, включая PATH
[/TD]
[TD]
“Дополнительные параметры системы” не отображают большинство переменных окружения, включая PATH
[/TD][/TR]
[TR][TD]
[/TD]
[TD]
После перезапуска системы, PATH больше не пустая, но обрезана до 2048 символов
[/TD]
[TD]
После перезапуска системы, PATH больше не пустая, но обрезана до 4096 символов
[/TD][/TR][/TABLE]
Решение проблемы даётся тоже весьма любопытное: перезагрузить систему, и она сама обрежет переменную до максимально допустимого размера.
Этого я, честно говоря, не наблюдал у себя, как и отказ системы запустить блокнот без указания полного пути. Но я особо и не пытался повторить эксперимент Intel. Может, у вас, читатели, это получится.
Заодно, и обратите внимание, что согласно статье Intel превышение длины значения PATH (больше 2047, и более серьёзные последствия, если больше 4095 символов) может привести к таким проблемам, как сбои в работе оснастки «Дополнительные параметры системы», а также других программ, зависящих от корректной работы этой переменной, т.к. значение обрезается.
Итог и решение проблемы.
Для однозначного решения проблемы остаётся второй вариант (также предложенный и в статье от Intel) – это обрезать значение самому.
После удаления лишних путей в строке PATH и приведения её длины до приемлемых размеров (меньше 2048 символов) я записал это значение через «Редактор реестра» в параметр PATH ключа HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.
Проблема решена.
А сегодня мой сканер работает нормально даже в моей основной системе. Уж не знаю, связана ли его проблема была с PATH или нет. Но лично я доволен.
А моя статья надеюсь, ещё принесёт кому-то пользу, как и увлекательный рассказ о процессе поиска виновника, который может сподвигнуть вас на использование похожих методов при поиске и решении других видов неисправностей.
Всем удачи!
Использованы материалы:
1. MSDN. Registry Elements Size Limits.
2. Karthiyayini C. (Intel). Limitation to the length of the System PATH variable.
3. remontka.pro - Как перезапустить Проводник explorer.exe в два клика
4. Мозг ^_^
Последнее редактирование: