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

发布于 2024-10-07 13:13:01 字数 254 浏览 0 评论 0原文

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

那么你有什么推荐呢? 很久以前,我尝试在属于该路径的目录中使用可执行文件的软链接,但这种方法不起作用。 将“仅可执行文件”扔到已知的目录中,存在几乎所有应用程序都需要一组文件的问题,因此这也很糟糕。 将可执行文件及其所有文件扔到一个已知的目录中,嗯,这可以工作,但是文件名发生冲突的可能性非常高。 创建硬链接?我不知道。你怎么认为?

I would like to know what are the approaches that you use to manage the executables in your system. For example I have almost everything accessible through the command line, but now I come to the limit of the path string, so i can't add any more dir.

So what do you recommend?
A long time ago, I tried to use softLinks of the executables in a Dir that belonged to the path, but that approach didn't work.
Throw the "executable only" to a known Dir,has the problems that almost any application require a set of files, so this also is bad.
Throw the executable and all his files to a known Dir, mmm this will work, but the possibility to get a conflict in the name of the files is very very high.
Create a HardLink? i don't know. What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

去了角落 2024-10-14 13:13:02

没有尝试过,但是将 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%

Didn't try it, but will splitting PATH in parts work and joining them in final variable work?

Example initially let's say you have something like

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

Instead you create:

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%
无人问我粥可暖 2024-10-14 13:13:01

这将解析您的 %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 变量。

This will parse your %PATH% environment variable and convert each directory to its shortname equivalent and then piece it all back together:

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

Take the output and update the PATH variable in environment variables.

一杯敬自由 2024-10-14 13:13:01

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

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%

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

%actualdir%\%actualfile% %args%

理想

echo %actualdir%\%actualfile% %args%

情况下,您应该在运行它之前确切地知道每一行的作用。

One way I can think of is to use other environment variables to store partial paths; for example, if you have

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

then you can create a new environment variable such as

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

after which your original paths become

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

EDIT: Another option is to create a bin directory that holds .bat files that point to the appropriate .exe files.

EDIT 2: Ben Voigt's comment to another answer mentions that using other environment variables as suggested might not reduce the length of %PATH% because they would be expanded prior to being stored. This may be true and I have not tested for it. Another option though is to use 8dot3 forms for longer directory names, for example C:\Program Files is typically equivalent to C:\PROGRA~1. You can use dir /x to see the shorter names.

EDIT 3: This simple test leads me to believe Ben Voigt is right.

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

At the end of this, you see output hellohello rather than byehello.

EDIT 4: In case you decide to use batch files to eliminate certain paths from %PATH%, you might be concerned about how to pass on arguments from your batch file to your executable such that the process is transparent (i.e., you won't notice any difference between calling the batch file and calling the executable). I don't have a whole lot of experience writing batch files, but this seems to work fine.

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

As a general rule, you should be careful about running batch files from the internet, since you can do all sorts of things with batch files such as formatting your hard drive. If you don't trust the code above (which I wrote), you can test it by replacing the line

%actualdir%\%actualfile% %args%

with

echo %actualdir%\%actualfile% %args%

Ideally you should know exactly what every line does before you run it.

贵在坚持 2024-10-14 13:13:01

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

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

将创建一个链接,因此 c:\pf 将成为您的程序文件 文件夹。通过使用这个技巧,我从我的路径中删除了 300 个字符。

if you are using windows vista or higher, you can make a symbolic link to the folder. for example:

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

would make a link so c:\pf would be your program files folder. I shaved off 300 characters from my path by using this trick.

时光瘦了 2024-10-14 13:13:01

如果有人感兴趣......

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

例如,如果我想在 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%

我发现这种方法相对干净,并且尚未遇到任何问题。

In case anyone's interested...

I find I never really need all those paths at once, so I create a bunch of "initialization" batch files which modify the path accordingly.

For example, if I wanted to do some C++ development in Eclipse, I would do:

> initmingw
> initeclipse
> eclipse

This is also handy for avoiding conflicts between executables with the same name (such as the C++ and D compilers, which both have a make.exe).

My batch files typically look like this:

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

I find this approach relatively clean and have yet to run into any problems with it.

往事风中埋 2024-10-14 13:13:01

我通常不必担心这一点(我没有遇到路径大小限制 - 我什至不知道现代 Windows 系统上的路径大小限制是什么),但我可以采取以下措施来避免将程序的目录放入路径:

  • 大多数命令行实用程序都会被放入路径上的 c:\util 目录中
  • 否则,我将向 c:\ 添加一个简单的 cmd/批处理文件util 目录看起来像:

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

这实际上为命令创建了一个别名。它不一定是完美的。有些程序确实坚持位于该路径中(现在这种情况相当罕见),而其他尝试调用它的程序可能无法正确找到它。但对于大多数用途来说它效果很好。

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

I generally don't have to worry about this (I haven't run into a path size limit - I don't even know what that is on modern Windows systems), but here's what I might do to avoid putting a program's directory in the path:

  • most command line utilities get thrown into a c:\util directory that's on the path
  • otherwise, I'll add a simple cmd/batch file to the c:\util directory that looks something like:

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

which essentially creates an alias for the command. It's not necessarily perfect. Some programs really insist on being in the path (that's pretty rare nowadays), and other programs that try to invoke it might not find it properly. But for most uses it works well.

But generally, I haven't had to worry about avoiding adding directories to the path.

明明#如月 2024-10-14 13:13:01

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

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

Another idea: Use DIR /X to determine the short names generated for non-8dot3 file
names. Then use these in your %PATH%.

For example, 'C:\Program Files' becomes 'C:\PROGRA~1'.

你的背包 2024-10-14 13:13:01

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

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

USe the App Path registry key instead of the path variable for application-specific paths:

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

怕倦 2024-10-14 13:13:01

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

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

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

使用这个软件,我只在我的路径中为我可能使用的所有程序设置了一个附加目录。

I wrote and use on a every-time basis a standard stream (stdin/stderr/stdout) & exit code PROXY program (called dispatcher https://github.com/131/dispatcher)

All CLI program i use (node, php, python, git, svn, rsync, plink ...) i'm using are actually the same exe file (around 10kb, that i just name differently), that i put in the same directory. A dummy static clear text file do the "proxy file name to real exe mapping".

Dispatcher use low level Process management win32 API to be absolutly transparent.

Using this software, i only do have ONE additionnal directory set in my PATH for all programs i might use.

反目相谮 2024-10-14 13:13:01

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

编辑:

创建一个虚拟驱动器。
subst p: "c:\程序文件"

Creating a folder c:\bin adding to your path and hardlinking like you said could shorten the string. Maybe add a variable pf to system vars with value c:\Program Files then replace c:\Program Files with %pf% in path.

Edit:

Create a virtual drive.
subst p: "c:\program files"

尐偏执 2024-10-14 13:13:01

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

  1. 为不同的软件包使用组合创建了不同的用户。
    示例: (a) 创建一个用户网站,以提供所有网络开发软件; (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 限制,则包含用于替换路径缩写链接的任何批处理。

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

您还可以在窗口内创建虚拟窗口。只要您拥有一份获得许可的操作系统副本,就可以使用同一密钥创建多个虚拟窗口。您可以将特定于该机器中的特定任务的包放入其中。您每次都必须启动单独的虚拟机。一些内存密集型软件包(例如 3D 动画电影制作器)都应该放入主机中,而不是放入 VM 中,因为 VM 将只有一部分 RAM 可供其使用。不过,启动每个虚拟机是一件很痛苦的事情。

I follow these steps to make the entries manageable:

  1. Created different users for different combination of software packages usage.
    Example: (a) Created a user web for making available all the web development software; (b) Created a user database for making available all the database and data warehousing software packages. Remember some software may create more than one entry. Or sometime I break this into oracle specific and MSSQL specific and oracle specific users. I put MySQL/PostgreSQL, tomcat, wamp, xamp all into the user account webr.

  2. If possible install common packages like office, photoshop, .. as system specific available for all users and special packages as user specific. Of course I had to log into different users and install them. Not all software may provide this option. If "install for this user only" option is not available, install it for the whole system.

  3. I avoid installing programs in to the folder Program File (x86) or in to Program File. I always install into the base directory. For example MySQL 64 bit goes into "C:\mysql64" and MySQL 32 bit goes into "C:\mysql" folder. I always assume adding a suffix 64 only for 64bit software. If no suffix, then it is a 32 bit. I follow the same thing to Java and others. This way my path will be shorter, not including "C:\Program File (x86)". For some software the configuration file may need to be edited to show where exactly the .exe file is. Only program that demands to be installed into "C:\Program File (x86)" will be installed into that folder. Always I remember to shorten the names. I avoid version number like tomcat/release/version-2.5.0.3 such details. If I need to the know version, I create a file by name version and put it into the tomcat folder. In general shorten the link as much as possible.

  4. Include any batch to replace abbreviated link to the path, if all the above steps passed the Windows limit.

Then Log into usage specific (mobile application, or database/data warehousing or web-development.. ..) user and do the relevant tasks.

You can also create virtual windows within windows. As long as you have one licensed OS copy, creating multiple virtual windows with same key is possible. You can put packages specific for a particular task in that machine. You have to launch separate VM each time. Some memory intensive packages like 3D animation movie makers all should be put into the main machine, not into VM as VM will have only a part of the RAM available for its use. It is a pain to boot each VM though.

兲鉂ぱ嘚淚 2024-10-14 13:13:01

仅当您能够缩减路径时,上述解决方案才有效。就我而言,这并不是一个真正的选择,而且每次打开命令提示符时都必须运行脚本很麻烦。因此,我编写了一个简单的脚本,该脚本在打开命令提示符时自动运行,并将文本文件的内容附加到您的路径中。

在某些情况下,运行此脚本会破坏某些内容(例如,在 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

要使其在启动时自动运行,请打开 regedit,导航到 HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Command Processor,然后右键单击右侧并按 new ->;多字符串值。将其命名为“自动运行”。将其值设置为

C:\Users\Yams\setUpPath.bat

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

The solutions above only work if you can trim down your path. In my case, that wasn't really an option, and it was a hassle to have to run a script every time I opened a command prompt. So I wrote a simple script that runs automatically when opening the command prompt, and appends the contents of a text file to your path.

There are also some contexts where having this script run breaks things (say, in a github or cygwin shell), so I also added a file that contains a list of paths that, if the command prompt is started in them, the path variable isn't changed via the startup script that normally updates the 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

And Path.txt will look something like

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;

While Dontsetup.txt will look something like

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

To make this run automatically on startup, open regedit, navigate to HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Command Processor, then right click on the right and press new -> Multi-String Value. Name it AutoRun. Set it's value to

C:\Users\Yams\setUpPath.bat

or wherever else you stored the batch file above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文