你如何避免在Windows中填充PATH环境variables?

我想知道你用什么方法来pipe理系统中的可执行文件。 例如我几乎所有的东西都可以通过命令行访问,但现在我已经到了pathstring的限制,所以我不能再添加目录。

那么你推荐什么? 很久以前,我试图在属于path的Dir中使用可执行文件的softLink,但是这种方法并不奏效。 把“仅执行文件”扔给一个已知的Dir,有几乎任何应用程序都需要一组文件的问题,所以这也是不好的。 把可执行文件和他的所有文件扔到一个已知的目录中,嗯,这将起作用,但是在文件名中出现冲突的可能性非常高。 创build一个HardLink? 我不知道。 你怎么看?

我能想到的一种方法是使用其他环境variables来存储部分path; 例如,如果你有

C:\this_is_a\long_path\that_appears\in_multiple_places\subdir1; C:\this_is_a\long_path\that_appears\in_multiple_places\subdir2; 

那么你可以创build一个新的环境variables如

 SET P1=C:\this_is_a\long_path\that_appears\in_multiple_places 

之后你的原始path成为

 %P1%\subdir1; %P1%\subdir2; 

编辑:另一种select是创build一个bin目录,其中包含指向相应的.exe文件的.bat文件。

编辑2:本Voigt对另一个答案的评论提到,使用其他环境variablesbuild议可能不会减less%PATH%的长度,因为它们将被存储之前展开。 这可能是真的,我还没有testing过。 另一个选项是使用8dot3格式来存放更长的目录名,例如C:\Program Files通常等同于C:\PROGRA~1 。 您可以使用dir /x来查看较短的名称。

编辑3:这个简单的testing使我相信本福伊特是正确的。

 set test1=hello set test2=%test1%hello set test1=bye echo %test2% 

在这最后,你会看到输出hellohello而不是byehello

编辑4:如果您决定使用batch file从%PATH%消除某些path,您可能会担心如何从batch file传递给您的可执行文件的参数,使该过程是透明的(即,你不会注意调用batch file和调用可执行文件之间的区别)。 我没有太多的经验写batch file,但这似乎工作正常。

 @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% 

作为一般的规则,你应该小心从互联网上运行batch file,因为你可以用batch file做各种事情,比如格式化你的硬盘。 如果你不信任上面的代码(我写的代码),你可以通过replace行来testing它

 %actualdir%\%actualfile% %args% 

 echo %actualdir%\%actualfile% %args% 

理想情况下,您应该确切知道每条线路在运行之前的function。

这将parsing您的%PATH%环境variables,并将每个目录转换为其相应的短名称,然后将它们全部重新组合在一起:

 @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! 

取出输出并更新环境variables中的PATHvariables。

如果您使用的是Windows Vista或更高版本,则可以创build文件夹的符号链接。 例如:

mklink /d C:\pf "C:\Program Files"

会做一个链接,所以c:\pf将是你的program files夹。 我使用这个技巧从我的path中删除了300个字符。

如果有人感兴趣…

我发现我从来没有真正需要所有这些path,所以我创build了一堆“初始化”batch file,相应地修改path。

例如,如果我想在Eclipse中做一些C ++开发,我会这样做:

 > initmingw > initeclipse > eclipse 

这对避免具有相同名称的可执行文件(如C ++和D编译器,它们都具有make.exe)之间的冲突也很方便。

我的batch file通常如下所示:

 @echo off set PATH=C:\Path\To\My\Stuff1;%PATH% set PATH=C:\Path\To\My\Stuff2;%PATH% 

我觉得这个方法比较干净,还没有遇到任何问题。

另一个想法:使用DIR / X来确定为非8dot3文件名称生成的短名称。 然后在你的%PATH%中使用这些。

例如,“C:\ Program Files”变为“C:\ PROGRA〜1”。

我通常不必担心这一点(我还没有遇到path大小的限制 – 我甚至不知道现代Windows系统上是什么),但是我可能会这么做以避免将程序的目录放入path:

  • 大多数命令行实用程序都被扔到path上的c:\util目录中
  • 否则,我将添加一个简单的cmd /batch file到c:\util目录,如下所示:

     @"c:\program files\whereever\foo.exe" %* 

这本质上为命令创build了一个别名。 这不一定是完美的。 有些程序确实坚持走在路上(现在很罕见),而其他试图调用它的程序可能找不到它。 但对于大多数使用它的效果很好。

但一般来说,我不必担心避免将path添加到path。

使用App Pathregistry项而不是应用程序特定path的pathvariables:

http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx

创build一个文件夹c:\ bin添加到你的path和硬链接就像你说的可以缩短string。 也许添加一个variablespf到系统variables值为c:\ Program Files,然后用path中的%pf%replacec:\ Program Files。

编辑:

创build一个虚拟驱动器。 subst p:“c:\ program files”

我遵循这些步骤使条目可pipe理:

  1. 为不同的软件包使用组合创build不同的用户。 例子:(a)创build一个用户网站,以提供所有的networking开发软件; (b)build立用户数据库,以提供所有数据库和数据仓库软件包。 记住一些软件可能会创build多个条目。 或者有时我把它分解成特定于Oracle的特定于MSSQL和特定于Oracle的用户。 我把MySQL / PostgreSQL,tomcat,wamp,xamp全部放到用户账户webr中。

  2. 如果可能的话,安装普通软件包,如office,photoshop等,作为系统特定的可用于所有用户和特殊软件包的用户特定。 当然,我必须login到不同的用户并安装它们。 并非所有的软件都可以提供此选项。 如果“仅为此用户安装”选项不可用,请将其安装到整个系统。

  3. 我避免将程序安装到程序文件(x86)文件夹或程序文件中。 我总是安装到基本目录。 例如MySQL 64位进入“C:\ mysql64”,MySQL 32位进入“C:\ mysql”文件夹。 我总是假设只为64位软件添加后缀64。 如果没有后缀,那么它是一个32位。 我遵循同样的事情Java和其他人。 这样我的path会更短,不包括“C:\ Program File(x86)”。 对于某些软件,可能需要编辑configuration文件以显示.exe文件的确切位置。 只有要求安装到“C:\ Program File(x86)”中的程序才会被安装到该文件夹​​中。 总是记得缩短名字。 我避免了像tomcat / release / version-2.5.0.3这样的细节版本号。 如果我需要知道的版本,我创build一个名称版本的文件,并把它放到tomcat文件夹。 通常尽可能地缩短链接。

  4. 如果上述所有步骤都通过了Windows限制,请包括任何批次以将缩略链接replace为path。

然后login到特定用途(移动应用程序,或数据库/数据仓库或Web开发..)用户并执行相关任务。

您也可以在窗口中创build虚拟窗口。 只要您拥有一个许可的操作系统副本,就可以使用相同的密钥创build多个虚拟窗口。 你可以把特定于某个特定任务的包放在那台机器上。 您必须每次启动单独的VM。 一些像3Danimation电影制造商这样的内存密集型的软件包都应该放在主机中,而不是虚拟机,因为虚拟机只有一部分内存可用。 尽pipe启动每个VM是一个痛苦。

我每次都写一个标准stream(stdin / stderr / stdout)并退出代码PROXY程序(称为调度程序https://github.com/ivsgroup/dispatcher

我使用的所有CLI程序(node,php,python,git,svn,rsync,plink …)我使用的都是相同的exe文件(大约10kb,我只是用不同的名称)目录。 虚拟静态清除文本文件执行“代理文件名称到真正的exe映射”。

调度员使用低级进程pipe理win32 API是绝对透明的。

使用这个软件,我只有一个额外的目录在我的path中设置我可能使用的所有程序。

上述解决scheme只有在您可以修剪您的path时才有效。 在我的情况下,这不是一个真正的select,每次打开命令提示符时都必须运行脚本,这是一件麻烦事。 所以我写了一个简单的脚本,在打开命令提示符时自动运行,并将文本文件的内容追加到path中。

还有一些上下文让脚本运行(例如,在github或者cygwin shell)中,所以我还添加了一个包含path列表的文件,如果在其中启动了命令提示符,pathvariablesisn通过通常更新path的启动脚本不会改变。

 @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 

和Path.txt看起来像

 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; 

而Dontsetup.txt会看起来像

 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 

要使其在启动时自动运行,请打开registry编辑器,导航到HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor,然后右键单击右键并按新build – >多string值。 将其命名为AutoRun。 设置它的值

 C:\Users\Yams\setUpPath.bat 

或上面存储batch file的位置。

没有尝试过,但是将部分工作中的PATH分开,并将其join最终的variables工作中?

例子最初让我们说你有类似的东西

PATH={LONGPATH1};{LONGPATH2};....{2048th char}....{LONGPATH_N-1};{LONGPATH_N}

相反,你创build:

 _PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char} _PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N} rem // may be more parts PATH = %_PATH1%;%_PATH2%