как избежать переполнения переменной среды path в windows?

<p>я хотел бы знать, какие подходы вы используете для управления исполняемыми файлами в вашей системе. например, у меня есть почти все доступное через командную строку, но теперь я дошел до предела строки пути, поэтому я не могу добавить больше dir.</p><p>итак, что вы порекомендуете? давным-давно я пытался использовать softlink-ы исполняемых файлов в dir, которые принадлежали пути, но этот подход не работал . бросить «только исполняемый файл» известный dir, имеет проблемы с тем, что почти любому приложению требуется набор файлов, так что это тоже плохо . бросьте исполняемый файл и все его файлы в известный dir, ммм это будет работать, но возможность получить конфликт в имя файлов очень, очень высокое . создать hardlink? я не знаю. как вы думаете?</p>

<p>один из способов, который я могу придумать, - это использовать другие переменные окружения для хранения частичных путей; например, если у вас есть</p><pre><code>c:\this\_is\_a\long\_path\that\_appears\in\_multiple\_places\subdir1; c:\this\_is\_a\long\_path\that\_appears\in\_multiple\_places\subdir2; </code></pre><p>затем вы можете создать новую переменную среды, такую как</p><pre><code>set p1=c:\this\_is\_a\long\_path\that\_appears\in\_multiple\_places </code></pre><p>после чего ваши первоначальные пути становятся</p><pre><code>%p1%\subdir1; %p1%\subdir2; </code></pre><p><strong> правка: </strong>другой вариант - создать каталог <code>bin</code>, содержащий файлы <code>.bat</code>, указывающие на соответствующие файлы <code>.exe</code>.</p><p><strong> правка 2: </strong>в комментарии бена фойгта к другому ответу упоминается, что использование других предложенных переменных среды может не уменьшить длину <code>%path%</code>, поскольку они будут расширены перед сохранением. это может быть правдой, и я не проверял это. другой вариант - использовать формы 8dot3 для более длинных имен каталогов, например, <code>c:\program files</code> обычно эквивалентен <code>c:\progra~1</code>. вы можете использовать <code>dir /x</code>, чтобы увидеть более короткие имена.</p><p><strong> правка 3: </strong>этот простой тест приводит меня к убеждению, что бен фойгт прав.</p><pre><code>set test1=hello set test2=%test1%hello set test1=bye echo %test2% </code></pre><p>в конце этого вы видите вывод <code>hellohello</code>, а не <code>byehello</code>.</p><p><strong> правка 4: </strong>если вы решите использовать пакетные файлы для исключения определенных путей из <code>%path%</code>, вы можете быть обеспокоены тем, как передать аргументы из вашего пакетного файла в ваш исполняемый файл, чтобы процесс был прозрачным (т. е. вы выиграли не замечаю никакой разницы между вызовом командного файла и вызовом исполняемого файла). у меня нет большого опыта написания командных файлов, но это, кажется, работает нормально.</p><pre><code>@echo off rem this batch file points to an executable of the same name rem that is located in another directory. specify the directory rem here: set actualdir=c:\this\_is\an\_example\_path rem you do not need to change anything that follows. set actualfile=%0 set args=%1 :beginloop if "%1" == "" goto endloop shift set args=%args% %1 goto beginloop :endloop %actualdir%\%actualfile% %args% </code></pre><p>как правило, вы должны быть осторожны с запуском пакетных файлов из интернета, поскольку с пакетными файлами вы можете делать все что угодно, например форматировать жесткий диск. если вы не доверяете приведенному выше коду (который я написал), вы можете проверить его, заменив строку</p><pre><code>%actualdir%\%actualfile% %args% </code></pre><p>с</p><pre><code>echo %actualdir%\%actualfile% %args% </code></pre><p>в идеале вы должны точно знать, что делает каждая строка, прежде чем запускать ее.</p>

<p>это проанализирует вашу переменную окружения% path% и преобразует каждый каталог в его краткий эквивалент, а затем объединит все вместе:</p><pre><code>@echo off set mypath=%path% echo %mypath% echo -- setlocal enabledelayedexpansion set temppath="%mypath:;=";"%" set var= for %%a in (%temppath%) do ( if exist %%~sa ( set "var=!var!;%%~sa" ) else ( echo %%a does not exist ) ) echo -- echo !var:~1! </code></pre><p>возьмите вывод и обновите переменную path в переменных окружения.</p>

<p>если вы используете windows vista или выше, вы можете сделать символическую ссылку на папку. например:</p><p><code>mklink /d c:\pf "c:\program files"</code></p><p>сделает ссылку, так что <code>c:\pf</code> будет вашей папкой <code>program files</code>. используя этот трюк, я сбрил с пути 300 персонажей.</p>

<p>если кому-то интересно ...</p><p>я обнаружил, что мне никогда не нужны все эти пути одновременно, поэтому я создаю набор командных файлов «инициализации», которые соответствующим образом изменяют путь.</p><p>например, если бы я хотел заняться разработкой c++ в eclipse, я бы сделал:</p><pre><code>> initmingw > initeclipse > eclipse </code></pre><p>это также удобно для избежания конфликтов между исполняемыми файлами с одинаковыми именами (например, компиляторами c++ и d, которые оба имеют make.exe).</p><p>мои командные файлы обычно выглядят так:</p><pre><code>@echo off set path=c:\path\to\my\stuff1;%path% set path=c:\path\to\my\stuff2;%path% </code></pre><p>я считаю этот подход относительно чистым и до сих пор не сталкивался с какими-либо проблемами.</p>

<p>как правило, мне не нужно беспокоиться об этом (я не сталкивался с ограничением размера пути - я даже не знаю, что это такое в современных системах windows), но вот что я мог бы сделать, чтобы не помещать каталог программы в путь:</p><ul> <li>большинство утилит командной строки выбрасываются в каталог <code>c:\util</code>, который находится по пути</li> <li><p>в противном случае я добавлю простой cmd/batch-файл в каталог <code>c:\util</code>, который будет выглядеть примерно так:</p> <pre><code>@"c:\program files\whereever\foo.exe" %* </code></pre></li> </ul><p>который по сути создает псевдоним для команды. это не обязательно идеально. некоторые программы действительно настаивают на том, чтобы быть на пути (это довольно редко в настоящее время), а другие программы, которые пытаются вызвать его, могут не найти его должным образом. но для большинства применений это работает хорошо.</p><p>но в целом мне не приходилось беспокоиться о том, чтобы не добавлять каталоги в путь.</p>

<p>другая идея: используйте dir/x, чтобы определить короткие имена, сгенерированные для файла не-8dot3 names. затем используйте их в вашем% path%.</p><p>например, «c:\program files» становится «c:\progra ~ 1».</p>

<p>используйте ключ реестра app path вместо переменной path для специфичных для приложения путей:</p><p> <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx</a> </p>

<p>я написал и использую каждый раз стандартный поток (stdin/stderr/stdout) и программу proxy с кодом выхода (называемую dispatcher <a href="https://github.com/131/dispatcher">https://github.com/131/dispatcher</a> ).</p><p>все программы cli, которые я использую (node, php, python, git, svn, rsync, plink ...), которые я использую, на самом деле являются одним и тем же exe-файлом (около 10 кб, который я просто называю по-разному), который я помещаю в один и тот же файл. каталог. фиктивный статический текстовый файл делает «имя файла прокси в реальном exe-отображении».</p><p>диспетчер использует низкоуровневый api управления процессами win32, чтобы быть абсолютно прозрачным.</p><p>используя это программное обеспечение, у меня есть только один дополнительный каталог, установленный в моем пути для всех программ, которые я мог бы использовать.</p>

<p>создание папки c:\bin, добавление к вашему пути и жесткие ссылки, как вы сказали, могут сократить строку. может быть, добавить системную переменную pf со значением c:\program files, а затем заменить c:\program files на% pf% в пути.</p><p>правка:</p><p>создать виртуальный диск . subst p: "c:\program files"</p>

<p>приведенные выше решения работают, только если вы можете урезать свой путь. в моем случае это не было возможным вариантом, и было сложно запускать скрипт каждый раз, когда я открывал командную строку. поэтому я написал простой скрипт, который запускается автоматически при открытии командной строки и добавляет содержимое текстового файла к вашему пути.</p><p>существуют также некоторые контексты, в которых запуск этого скрипта нарушает работу (скажем, в github или cygwin shell), поэтому я также добавил файл, содержащий список путей, который, если в них запущена команда prompt, переменная path isn не изменяется с помощью сценария запуска, который обычно обновляет путь.</p><pre><code>@echo off :: modify these to the actual paths of these two files set dontsetupfile=c:\users\yams\dontsetup.txt set pathfile=c:\users\yams\path.txt :: retrieve the current path (for determining whether or not we should append to our path) set curdir=%cd% :: be done if the current path is listed in the dontsetupfile setlocal enabledelayedexpansion for /f "delims=" %%i in (%dontsetupfile%) do ( if "%%i"=="%curdir%" goto alldone ) :: append the pathfile to our current path set pathappend= for /f "delims=" %%i in (%pathfile%) do (set pathappend=!pathappend!%%i) set path=%path%;%pathappend% :: the only way to actually modify a command prompt's path via a batch file is by starting :: up another command prompt window. so we will do this, however, if this script is :: automatically called on startup of any command prompt window, it will infinately :: recurse and bad things will happen. :: if we already ran, we are done if "%yams%"=="onion" goto alldone :: otherwise, flag that we just ran, and then start up a new command prompt window :: with this flag set set yams=onion cmd \k set path=%path%; :: when that command prompt exits, it will load back up this command prompt window, and :: then the user will need to exit out of this as well. this causes this window to :: automatically exit once the cmd it just spawned is closed. exit() :: path is set up, we are done! :alldone @echo on </code></pre><p>и path.txt будет выглядеть примерно так</p><pre><code>c:\program files (x86)\google\google\_appengine; c:\program files (x86)\ati technologies\ati.ace\core-static; c:\program files (x86)\nvidia corporation\physx\common; c:\program files\microsoft sql server\110\tools\binn; c:\program files\microsoft dnx\dnvm; c:\program files (x86)\windows kits\8.0\windows performance toolkit; </code></pre><p>пока dontsetup.txt будет выглядеть примерно так</p><pre><code>c:\program files (x86)\windows kits\8.0\windows performance toolkit c:\program files (x86)\git\cmd c:\program files (x86)\microsoft visual studio 14.0\vc\bin </code></pre><p>чтобы автоматически запустить его при запуске, откройте regedit, перейдите к hkey\_local\_machine/software/microsoft/command processor, затем щелкните правой кнопкой мыши справа и нажмите new -> multi-string value. назовите это autorun. установите это значение </p><pre><code>c:\users\yams\setuppath.bat </code></pre><p>или где бы вы ни сохранили командный файл выше. </p>

<p>не пробовал, но будет ли разделять path на части и объединять их в конечную переменную работу?</p><p>пример изначально скажем у вас что то типа</p><p><code>path={longpath1};{longpath2};....{2048th char}....{longpath\_n-1};{longpath\_n}</code></p><p>вместо этого вы создаете:</p><pre><code>\_path1 = {longpath1};{longpath2};....{2048 char} \_path2 = {2049th char}...{longpath\_n-1};{longpath\_n} rem // may be more parts path = %\_path1%;%\_path2% </code></pre>

<p>я следую за этими шагами, чтобы сделать записи управляемыми:</p><ol> <li><p>созданы разные пользователи для разных комбинаций использования пакетов программного обеспечения .. пример. (a) создан пользовательский веб-сайт для обеспечения доступности всего программного обеспечения для веб-разработки; (b) создана пользовательская база данных для предоставления доступа ко всем программным пакетам базы данных и хранилищ данных. помните, что некоторые программы могут создавать более одной записи. или когда-нибудь я разбиваю это на конкретных oracle, mssql и oracle. я поместил mysql/postgresql, tomcat, wamp, xamp все в учетную запись пользователя webr.</p></li> <li><p>если возможно, установите общие пакеты, такие как office, photoshop, .. как системные, доступные для всех пользователей, и специальные пакеты как пользовательские. конечно, мне пришлось войти в систему разных пользователей и установить их. не все программное обеспечение может предоставить эту опцию. если опция «установить только для этого пользователя» недоступна, установите ее для всей системы.</p></li> <li><p>я избегаю установки программ в папку program file (x86) или в program file. я всегда устанавливаю в базовый каталог. например, 64-разрядная версия mysql помещается в папку «c:\mysql64», а 32-разрядная версия mysql - в папку «c:\mysql». я всегда предполагаю добавление суффикса 64 только для 64-битного программного обеспечения. если суффикса нет, то это 32 бит. я следую за тем же самым на яве и других. таким образом, мой путь будет короче, не считая «c:\program file (x86)». для некоторых программ может потребоваться отредактировать файл конфигурации, чтобы показать, где именно находится файл .exe. в эту папку будет установлена только программа, которая требует установки в «c:\program file (x86)». всегда помню, чтобы сократить имена. я избегаю таких версий версии как tomcat/release/version-2.5.0.3. если мне нужна известная версия, я создаю файл по имени версии и помещаю его в папку tomcat. в общем, сократите ссылку как можно больше.</p></li> <li><p>включите любой пакет для замены сокращенной ссылки на путь, если все вышеперечисленные шаги прошли ограничение windows.</p></li> </ol><p>затем войдите в систему для конкретного пользователя (мобильное приложение, база данных/хранилище данных или веб-разработка ...) и выполните соответствующие задачи.</p><p>вы также можете создавать виртуальные окна внутри окон. пока у вас есть одна лицензионная копия ос, возможно создание нескольких виртуальных окон с одним и тем же ключом. вы можете поместить пакеты, специфичные для конкретной задачи, на этом компьютере. вы должны запускать отдельный vm каждый раз. некоторые пакеты с интенсивным использованием памяти, такие как создатели 3d-анимационных фильмов, должны быть помещены на основной компьютер, а не в vm, поскольку vm будет иметь только часть ram, доступную для его использования. хотя загружать каждый vm очень сложно.</p>