如何避免在Windows中过度填充PATH环境变量?

时间:2010-12-10 02:18:56

标签: windows path environment-variables executable

我想知道您用来管理系统中可执行文件的方法是什么。例如,我几乎可以通过命令行访问所有内容,但现在我达到了路径字符串的限制,所以我无法再添加dir。

那么你推荐什么? 很久以前,我尝试在属于路径的Dir中使用可执行文件的softLinks,但这种方法不起作用。 将“只有可执行文件”抛给已知的Dir,几乎任何应用程序都需要一组文件,所以这也很糟糕。 将可执行文件和他的所有文件都抛给一个已知的Dir,mmm这样可以工作,但是在文件名中出现冲突的可能性非常高。 创建一个HardLink?我不知道。你觉得怎么样?

12 个答案:

答案 0 :(得分:82)

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

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

然后您可以创建一个新的环境变量,例如

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

之后您的原始路径变为

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

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

编辑2: Ben Voigt对另一个答案的评论提到,建议使用其他环境变量可能不会缩短%PATH%的长度,因为它们会在存储之前进行扩展。这可能是真的,我还没有测试过。另一个选择是将8dot3表单用于更长的目录名称,例如C:\Program Files通常等同于C:\PROGRA~1。您可以使用dir /x查看较短的名称。

编辑3:这个简单的测试让我相信Ben Voigt是对的。

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

在这结束时,您会看到输出hellohello而不是byehello

编辑4:如果您决定使用批处理文件来消除%PATH%中的某些路径,您可能会担心如何将批处理文件中的参数传递给可执行文件,例如该过程是透明的(即,您不会注意到调用批处理文件和调用可执行文件之间的任何区别)。我没有很多编写批处理文件的经验,但这似乎工作正常。

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

作为一般规则,您应该小心从Internet运行批处理文件,因为您可以使用批处理文件(例如格式化硬盘驱动器)执行各种操作。如果你不相信上面的代码(我写的),你可以通过替换行

来测试它
%actualdir%\%actualfile% %args%

echo %actualdir%\%actualfile% %args%

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

答案 1 :(得分:78)

这将解析你的%PATH%环境变量,并将每个目录转换为其等效的短名称,然后将它们全部重新组合在一起:

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

获取输出并更新环境变量中的PATH变量。

答案 2 :(得分:28)

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

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

会建立一个链接,以便c:\pf成为您的program files文件夹。通过使用这个技巧,我从我的路径中削减了300个字符。

答案 3 :(得分:10)

万一有人感兴趣......

我发现我从来没有真正需要所有这些路径,所以我创建了一堆“初始化”批处理文件,相应地修改了路径。

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

> initmingw
> initeclipse
> eclipse

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

我的批处理文件通常如下所示:

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

我发现这种方法比较干净,并且还没有遇到任何问题。

答案 4 :(得分:6)

我通常不必担心这个问题(我没有遇到路径大小限制 - 我甚至不知道现代Windows系统上有什么),但这是我可能做的以避免放置程序在路径中的目录:

  • 大多数命令行实用程序被抛入路径
  • c:\util目录
  • 否则,我会在c:\util目录中添加一个简单的cmd / batch文件,如下所示:

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

基本上为命令创建别名。它不一定完美。有些程序真的坚持走在路上(现在很少见),其他试图调用它的程序可能找不到它。但对于大多数用途来说,效果很好。

但一般来说,我不必担心避免在路径中添加目录。

答案 5 :(得分:5)

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

例如,'C:\ Program Files'变为'C:\ PROGRA~1'。

答案 6 :(得分:5)

使用App Path注册表项而不是特定于应用程序的路径的路径变量:

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

答案 7 :(得分:1)

创建一个文件夹c:\ bin添加到你的路径并像你说的那样硬连接可以缩短字符串。也许将变量pf添加到值为c的系统变量:\ Program Files然后用路径中的%pf%替换c:\ Program Files。

编辑:

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

答案 8 :(得分:1)

我在每次编写和使用标准流(stdin / stderr / stdout)&退出代码PROXY程序(称为调度程序https://github.com/131/dispatcher

我使用的所有CLI程序(node,php,python,git,svn,rsync,plink ......)我使用的实际上是相同的exe文件(大约10kb,我只是命名不同),我把它在同一目录中。虚拟静态明文文件执行“代理文件名到真实exe映射”。

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

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

答案 9 :(得分:0)

我按照以下步骤使条目易于管理:

  1. 为不同的软件包使用组合创建了不同的用户。 示例:(a)创建用户Web以提供所有Web开发软件; (b)创建用户数据库,以提供所有数据库和数据仓库软件包。请记住,某些软件可能会创建多个条目。或者有时我将其分解为oracle特定的和MSSQL特定的和oracle特定的用户。我将MySQL / PostgreSQL,tomcat,wamp,xamp全部放入用户帐户webr。

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

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

  4. 如果上述所有步骤都超过了Windows限制,请包含任何批次以将缩写链接替换为路径。

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

    您还可以在Windows中创建虚拟窗口。只要您拥有一个许可的OS副本,就可以使用相同的密钥创建多个虚拟窗口。您可以将特定任务的包放在该计算机中。您必须每次启动单独的VM。一些内存密集型软件包(如3D动画电影制作者)都应该放入主机,而不是放入VM,因为VM只有一部分RAM可供其使用。尽管引导每个VM是一件痛苦的事。

答案 10 :(得分:0)

上述解决方案只有在您可以减少路径时才有效。在我的情况下,这不是一个真正的选项,每次打开命令提示符时都必须运行脚本是一件麻烦事。所以我编写了一个简单的脚本,在打开命令提示符时自动运行,并将文本文件的内容附加到路径中。

还有一些上下文运行这个脚本会破坏事物(例如,在github或cygwin shell中),所以我还添加了一个文件,其中包含一个路径列表,如果在它们中启动命令提示符,则路径变量不会通过通常更新路径的启动脚本进行更改。

@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

要在启动时自动运行,请打开注册表,导航到HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor,然后右键单击右键并按新 - >多字符串值。将其命名为AutoRun。将其值设置为

C:\Users\Yams\setUpPath.bat

或您在上面存储批处理文件的任何其他位置。

答案 11 :(得分:0)

没有尝试过,但是会在部分工作中分割PATH并将它们加入到最终变量工作中吗?

最初的例子让我们说你有像

这样的东西

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

而是创建:

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