Статья Дело о заблокированной переменной окружения %PATH%. Переменная среды path
Дело о заблокированной переменной окружения %PATH%
Дело о заблокированной переменной окружения %PATH%.
Автор: DragokasКак-то раз мне потребовалось отсканировать документ, но при попытке открыть интерфейс сканера появилась ошибка:
Согласно одному из советов на официальном сайте было предложено добавить папку с библиотеками сканера в переменную PATH, что я и сделал по своей же инструкции:
- Скопировал в буфер обмена нужный путь (у меня это «C:\Windows\twain_32\CNQL25», без кавычек)
- Открыл оснастку «Система» быстрой комбинацией Win + R
- Нажал слева «Дополнительные параметры» => «Переменные среды»
- В группе «Системные переменные» нашел переменную PATH, «Изменить»
- Поставил курсор в конец строки с полем «Значение переменной» и убедился, что в конце строки есть знак «точка с запятой»
- И нажал «Вставить из буфера» по ПКМ.
Но ничего не вставилось, а в колонках раздался радостный звук «Дзыньк» =)))
Первая мысль – в буфер обмена ничего не скопировалось (хотя в этом случае пункт «Вставить» должен был быть серым).Ну да ладно, гадать не буду, и решил просто вручную набрать путь с клавиатуры.Но не тут-то было.В ответ всё те же радостные звуки «Дзыньк-дзыньк».
Неисправна клавиатура?
Да нет же, проверил в блокноте, всё нормально набирается.Что же делать?
1. Способ дилетанта
PATH можно заменить несколькими способами, и поскольку мне нужно было срочно отсканировать документ, мне было все равно как это сделать, и не было времени разбираться с ошибкой.
PATH – это особая переменная, которая собирается из двух параметров PATH в ключах реестра:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\EnvironmentHKEY_CURRENT_USER\Environment (по-умолчанию, здесь параметра PATH нет).
Учитывая, что у меня на полочке лежит недописанная статья о переменных окружения, было нетрудно «вспомнить» этот путь, перейти туда, открыв «Редактор реестра» (Win + R, regedit), и отредактировать значение параметра 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Получили «Отказано в доступе».Любопытно.
Всё таки: проблемы в правах?
А что если просто распечатать содержимое?
Вот так новость. Я её даже не могу распечатать!
Попробуем с правами администратора?
Именем святого Админа, запускаем командную строку:
Нет, всё же, не везёт нам.
Может дело просто в каких-то спецсимволах в путях? Ком. строка очень не любит всякие птички ^, скобки и прочее.
Давайте заключим содержимое в кавычки:
Вуаля
И даже работает присвоение:
CMD/BATCH:
set "Path=%Path%;C:\Windows\twain_32\CNQL25" Хорошо. Но в чём именно проблема? Я скопировал в блокнот всё значение (взял из реестра). И методом половинного деления начал подставлять эту строку в echo.В итоге выяснилось, что где-то в средину пути попала такая штука:
Символ перенаправления строки в файл >.В итоге, вместо того, чтобы распечатать строку на экран консоли, она пыталась вывести её в файл C:\Windows\System32;C:\Windows;C:\Wi… не являющийся корректным именем. Из-за чего и возникала ошибка «Отказано в доступе»
А что же на счёт системы?> - это недопустимый символ для пути. Получается, всё это время система «глючила» из-за него?
Открыв редактор реестра, я удалил знак > из параметра PATH.(заодно заметив, что у меня 2 раза повторяются все пути, но пока решил это не трогать).
ОК, ещё раз захожу в оснастку «Система» в «переменные окружения», пытаюсь изменить значение PATH, и … снова не получается.Но тут всё понятно:
Известно, что каждый процесс хранит в памяти блок переменных окружения, и не изменяет его, пока система не отправит специальное сообщение. И даже в этом случае процесс не обязан обновить переменные.
Так что мы просто перезапустим процесс explorer, который отвечает за загрузку окон оснасток (напомню, это можно сделать через Ctrl + Shift + ПКМ по окну в меню «Пуск»).
Или, что более надёжно, перезагрузим всю систему.
Вот уже появились ярлычки. Захожу, проверяю, и …
Каково было удивление, но ничего не сработало. Символы опять не печатаются в поле «Значение переменной». ))))
Но не отчаиваемся. Остался один очевидный факт:1) Два раза дублируются пути2) Строка с содержимым Path какая-то уж слишком длинная3) Заметил, что в поле «Значение переменной» хоть и нельзя печатать, но можно удалять символы.
Итак, ограничение по длине?
Но, какого рода лимит?Может, предел для длины значения параметра реестра?Открываем базу знаний Micosoft: Registry Elements Size Limits.
Там говорят:
Value name16,383 charactersWindows 2000: 260 ANSI characters or 16,383 Unicode characters.
А наша строка = 2271 символов. Пишут, что в Win2k был жесткий лимит – в 260, но это только для ANSI-версий API-функций, а внутренне – строки хранятся в реестре все равно в Unicode. Точнее, в смешанном виде ANSI + Unicode (механизм оптимизации, детальнее о котором писал Руссинович в «Windows Internals»). Да и у меня под руками Windows 7, так что не вариант.Эксперимент.Поскольку оснастка даёт нам право удалять символы, а давайте так и сделаем.Будем удалять их до тех пор, пока текстовое поле не позволит нам вводить новые символы.
И… ура, сработало
После нескольких десятков удалённых, нам позволили наконец-то вводить новые символы (не пришлось даже нажимать кнопку «ОК»).
Давайте же замерим, сколько получилось в итоге максимальное число символов.
Мой любимый AkelPad показывает что их – 2047.
Вот как. И что же за магическое число 2047 ?
Спросим у великого гуру – Google: «Path limit 2047»
Первая же ссылка ведёт на довольно любопытную статью от Karthiyayini C. (из Intel): Limitation to the length of the System PATH variable.
В ней даётся таблица с симптомами «переполнения» переменной PATH, когда её длина >= 2048 символов:
< 2048 байтов | Всё работает прекрасно | Всё работает прекрасно |
>= 2048 и < 4096 байтов | 1. PATH пустой в командной строке (echo %PATH%) | 1. PATH пустой в командной строке (echo %PATH%) |
2. Нельзя запустить приложение из-под командной строки без указания полного пути (notepad.exe) | 2. Нельзя запустить приложение из-под командной строки без указания полного пути (notepad.exe) | |
3. Можно запустить приложение из-под командной строки, указав полный путь (c:\windows\system32\notepad.exe) | 3. Можно запустить приложение из-под командной строки, указав полный путь (c:\windows\system32\notepad.exe) | |
4. Windows Explorer работает прекрасно | 4. Windows Explorer работает прекрасно | |
5. Можно запустить “Панель Управления\Система\Дополнительные параметры системы” | 5. Невозможно запустить “Панель Управления\Система\Дополнительные параметры системы” | |
6. Можно получить “Дополнительные параметры системы” из-под командной строки %WinDir%\System32\SystemPropertiesAdvanced.exe | 6. Можно получить “Дополнительные параметры системы” из-под командной строки %WinDir%\System32\SystemPropertiesAdvanced.exe | |
7. “Дополнительные параметры системы” могут отобразить все переменные окружения, включая PATH | 7. Дополнительные параметры системы” могут отобразить все переменные окружения, включая PATH | |
8. После перезапуска системы, PATH больше не пустая, но обрезана до 2048 символов | 8. После перезапуска системы PATH больше не пустая и ведёт себя нормально | |
>= 4096 байтов | пп. 1, 2, 3, 4, 5 и 6 так же, как выше | пп. 1, 2, 3, 4, 5 и 6 так же, как выше |
“Дополнительные параметры системы” не отображают большинство переменных окружения, включая PATH | “Дополнительные параметры системы” не отображают большинство переменных окружения, включая PATH | |
После перезапуска системы, PATH больше не пустая, но обрезана до 2048 символов | После перезапуска системы, PATH больше не пустая, но обрезана до 4096 символов |
Решение проблемы даётся тоже весьма любопытное: перезагрузить систему, и она сама обрежет переменную до максимально допустимого размера.
Этого я, честно говоря, не наблюдал у себя, как и отказ системы запустить блокнот без указания полного пути. Но я особо и не пытался повторить эксперимент 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. Мозг ^_^
safezone.cc
Различная переменная среды PATH для 32-битной и 64-битной Windows – возможно ли это? Bilee
Да, это абсолютно возможно. Просто напишите три файла .bat. Первый должен выглядеть следующим образом:
@echo off if "%1" == "" goto x86 if not "%2" == "" goto usage if /i %1 == x86 goto x86 if /i %1 == ia64 goto ia64 goto usage :x86 if not exist "%~dp0bin\x86.bat" goto missing call "%~dp0bin\x86.bat" goto :eof :ia64 if not exist "%~dp0bin\ia64.bat" goto missing call "%~dp0bin\ia64.bat" goto :eof :usage echo Error in script usage. The correct usage is: echo %0 [option] echo where [option] is: x86 ^| ia64 echo: echo For example: echo %0 x86 goto :eof :missing echo The specified configuration type is missing. The tools for the echo configuration might not be installed. goto :eofВторой и третий .bat-файлы в основном одинаковы, за исключением того, что они отличаются от их имени. Первый будет называться x86.bat второй ia64.bat, и они помещаются в папку с именем bin, которая находится над первым файлом bat. У вас будет следующее:
PATH\first.bat PATH\bin\x86.bat PATH\bin\ia64.batСодержимое второго и третьего .bat-файлов должно выглядеть следующим образом:
@set PATH=THE PATH YOU WANTВы можете создать ссылку на первый .bat-файл, который будет иметь следующие настройки:
Цель:% comspec% / k "PATH \ first.bat" ОПЦИЯ | Где ОПЦИЯ – x86 или ia64
Начало работы: PATH | Где PATH – это PATH для вашего first.bat
Скрипт – это упрощенный сценарий, который Microsoft использует для запуска правильной командной строки для среды Visual Studio. Вы можете просто расширить эти сценарии до N окружений. Добавляя больше .bat-файлов для разных сред и редактируя first.bat с большим количеством опций и операторов goto. Надеюсь, это объяснение.
И я надеюсь, что Microsoft не подаст в суд на меня за использование своего сценария.
РЕДАКТИРОВАТЬ:
Ах, я думаю, что я немного вас понял. Для 32-разрядной линии cmd ссылка должна быть создана как:
Цель:% windir% \ SysWoW64 \ cmd.exe "PATH \ first.bat" x86
EDIT2:
Попробуйте что-нибудь вроде:
if "%ProgramFiles%" == "%ProgramFiles(x86)%" goto x64_PATH if "%ProgramFiles%" == "%ProgramW6432%" goto x86_PATH :x64_PATH @set PATH=YOUR 64 bit PATH SOME_PATH\your64BitApp.exe goto :eof :x86_PATH @set PATH=YOUR 32bit PATH SOME_PATH\your32BitApp.exe goto :eofwww.bilee.com
[решено] W7 Не работает переменная среды PATH
Вопрос: Переменные среды в командной строке
Переменные средыАвтор: specialist, Вадим Стеркин aka Vadikan
Переменные среды, используемые в (командных) файлах, позволяют обходиться без указания абсолютных путей к директориям. Например, если нам заранее неизвестна буква системного диска, мы всегда можем использовать переменную %systemdrive%, возвращающую букву диска, на котором установлена ОС. Также, переменные применяются для оптимизации кода - многократно повторяющемуся параметру (например, разделе реестра) можно назначить короткую переменную и использовать ее. В данной статье подробно рассматриваются различные приемы работы с переменными, а также способы изменения и создания новых переменных. Теперь обо всем по порядку.
Классификация переменных среды
Справка Windows различает два типа переменных среды: системные и локальные. Системные переменные возвращают одинаковые значения для всех пользователей. К примеру, %systemdrive% - буква системного диска, и она для всех пользователей одинакова. А вот значения, возвращаемые локальными переменными, варьируются в зависимости от вошедшего в систему пользователя. Например, %userprofile% может возвращать C:\Documents and Settings\ТекущийПользователь, где ТекущийПользователь - название учетной записи пользователя.
Узнать, какие переменные среды в операционной системе вам доступны и какие значения в данный момент им присвоены, вам поможет команда SET, запущенная из командной строки без параметров (Пуск – Выполнить – cmd – set). В рамках данной статьи нас интересуют переменные, обозначающие путь к различным папкам (каталогам). Чуть подробнее о некоторых из них ниже:
%SYSTEMDRIVE% | Системная | Возвращает имя диска, содержащего корневой каталог операционной системы /2003 (т. е. системный корневой каталог). |
%SYSTEMROOT%, %WINDIR% | Системная | Возвращает размещение корневого каталога операционной системы Windows /2003 |
%PATH% | Системная | Указывает путь для исполняемых файлов. |
%PROGRAMFILES% | Системная | Указывает путь к каталогу установки программ (Program Files) |
%COMMONPROGRAMFILES% | Системная | Указывает путь к общему каталогу программ (Program Files\Common Files). |
%TEMP% и %TMP% | Системная и пользовательская | Возвращает временные папки, по умолчанию используемые приложениями, которые доступны пользователям, выполнившим вход в систему. Некоторые приложения требуют переменную TEMP, другие — переменную TMP. |
%USERPROFILE% | Локальная | Возвращает размещение профиля для текущего пользователя. |
%ALLUSERSPROFILE% | Локальная | Возвращает размещение профиля "All Users". |
%CD% | Локальная | Возвращает путь к текущей папке. |
%APPDATA% | Локальная | Возвращает используемое по умолчанию размещение данных приложений. |
Начнем с простенького примера:
Код Code | ||
|
Во всех командах я специально использовал "кавычки" – это не случайно. Весь путь, включая переменные, надо заключать в кавычки, если вы используете пути, содержащие пробелы. Даже если сама переменная кавычек не содержит, после ее разбора системой в пути могут появится пробелы (например, %ProgramFiles% в C:\Program Files). В любом случае кавычки лучше использовать – это является хорошим тоном оформления командных файлов.
Как задать свои переменные
Разобранный выше пример использовал уже существующие переменные среды. И вы, вероятно, обратили внимание на символы процентов, окружающие названия переменных. Эти символы нужны для того, чтобы разрешить подстановку значений переменной в командной строке или в пакетном файле. Символы процентов указывают на то, что должна обратиться к значениям переменных, а не делать посимвольное сравнение. Ниже вы увидите, как это работает. Задать свои переменные в пакетном файле можно командой SET.
Команда SET Вы можете задать в командном файле свои переменные при помощи все той же команды SET.
Чтобы добавить переменную, введите в командной строке:
Код Code | ||
|
Код Code | ||
|
Код Code | ||
|
Код Code | ||
|
Важное примечание: переменные, задаваемые командой set, действуют лишь на протяжении командной сессии (см. ниже), в которой они были заданы.
Эти переменные могут быть созданы, к примеру, для любых путей, надо лишь задать или алгоритм присвоения переменной в каждой частной ситуации, пользуясь готовыми примерами или создавая свои на их основе. Как правило, такие переменные создаются в текущей сессии командными файлами с помощью некоторых операторов.
Пример назначения переменных в файле RunOnceEx.cmd, импортирующем параметры в реестр
Код Code | ||
|
Код Code | ||
|
Код Code | ||
|
Пример назначения переменных в командном файле, устанавливающем приложение с CD:
Код Code | ||
|
Изменение переменных среды и добавление собственных переменных
Как уже было сказано выше, действие переменных, заданных командой set, ограничивается текущей командной сессией. Если вы хотите получить из временной переменной системную или пользовательскую, то надо ее прописать в реестр. Сделать это тоже можно различными способами.
Утилита setenv Утилита работает из командной строки (, ). Работать с утилитой очень просто (setenv /?).
Пользовательские настройки | setenv -u имя_переменной значение |
Системные настройки | setenv -m имя_переменной значение |
Настройки Default User | setenv -d имя_переменной значение |
Настройки текущего пользовательского сеанса | setenv -v имя_переменной значение |
Код Code | ||
|
Код Code | ||
|
Если же пойти путем внесения изменений в реестр после первого входа в систему, то переменные начнут "работать" только после перезагрузки или завершения пользовательского сеанса. Конечно, в процессе автоустановки можно импортировать желаемые параметры на Т-12 (см. статью ) и обойти данную проблему. Если же вы не собираетесь использовать назначенную переменную в текущем пользовательском сеансе, то импорт в реестр вас тоже может устроить. Процесс импорта REG-файлов описывать повторно не буду, а рассмотрю команду REG ADD на конкретном примере.
Допустим, вы заинтересованы иметь в системе переменную %CDROM% на постоянной основе и установить ее в процессе установки приложений с CD. Следуя коду, приведенному выше, нужно после определения переменной назначить ее системной.
Код Code | ||
|
Резюме
Командная оболочка Windows (cmd.exe) - это весьма мощный инструмент работы с системой. При помощи пакетных файлов можно автоматизировать изрядное количество задач, и именно поэтому они часто используются для автоматической установки Windows. Умелое использование переменных в пакетных файлах позволяет решать широкий спектр вопросов. Работа с командной оболочкой становится более эффективной и одновременно упрощается код пакетных файлов. Другие примеры использования переменных вы можете найти на страницах сайта или форума. Все примеры, использованные в этой статье, взяты из скриптов участников форума OsZone.ru, за что им большое спасибо.
Терминология
Командная оболочка — это отдельный программный продукт, который обеспечивает прямую связь между пользователем и операционной системой. Текстовый пользовательский интерфейс командной строки предоставляет среду, в которой выполняются приложения и служебные программы с текстовым интерфейсом.
cmd.exe - интерпретатор команд, который командная оболочка ОС Windows использует для перевода введенной команды в формат, понятный системе.
Командная сессия может инициироваться как запуском cmd.exe, так и запуском пакетного файла. Иными словами создается текущая командная оболочка. Соответственно выход из этой оболочки (к примеру, окончание работы пакетного файла) завершает командную сессию.
Пользовательский сеанс (пользовательская сессия) начинается с момента входа пользователя в систему (log on) и завершается при выходе (log off).
forundex.ru