How do you avoid over-populating the PATH Environment Variable in Windows?
Asked Answered
R

12

122

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?

Raynard answered 10/12, 2010 at 2:18 Comment(3)
why you use so much paths? path is usually use for common dir, when your app must sharing extend object/app/lib with others. Use so much make app start slower. Can you give more detail about how you using, create path environment var?Infighting
hi pinichi, well a lot of applications use the standard "C:\Program File\AppNAme\...", and in my case a lot of this applications can run in a command line fashion or need to be accessible to other apps (for example the executables of Miktex that any Tex editor expect that exist), so they need to be in the PATH. I wan't to know a better approach because mine is unsustainableRaynard
This tool will compress the paths. The result is impressive: uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337Megalopolis
S
85

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.

Sizable answered 10/12, 2010 at 2:32 Comment(14)
the 8dot3 form works good, but for directories real big isn't too great, for instance "C:\Program Files (x86)\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Tools\Sandcastle\ProductionTools\". Another thing that save a little was that as a user i could create a PATH variable based in the System Path, and add any other Dir. All of this approaches are of the type "compact that string", but can we have a centralized directory of binaries, as has Unix?Raynard
Hmm, regarding very long directories, I would think the opposite is true: the longer the directory, the more characters you save by using 8dot3 format. If it's hard to navigate in cmd, note that you can use * to save typing. So for example, from root, type in dir /x pro*. You will see your desired directory there along with its 8dot3 name. Then use cd to navigate to it and repeat the process.Sizable
i say that isn't too great in the sense that compressing his length perhaps being a valid solution( that i'm definitely begin to use) don't remove the root problem...having the Path variable overflowed with different directoriesRaynard
Regarding UNIX, there you have $PATH which works very similarly to %PATH% in Windows, so I'm not sure what your point is exactly. By convention, UNIX directory names tend to be shorter than in Windows, and as a result $PATH also tends to be shorter.Sizable
Thanks Mitch, the Edit 4 that you provide is what I wanted!, now i can have centralized folder with all the binaries that i need. I'm going to testing more in deep to see if there is a problem with some appRaynard
hi Mitch i tested in various cases, and the only complain that i have is that for example when you run it from the execute menu, it open a cmd prompt in behind and then open the app that i want,...is there a possibility to hide this prompt?Raynard
@voodoomsr, I cannot reproduce what you described. What version of Windows are you using? Can you give any more details? I did notice while trying to reproduce your results that Windows Vista (32-bit Home Premium SP1) will give the full path along with .bat and quotes as %0 and thus you would need to modify the script accordingly for this use; simplest way (although you lose generality) is to manually set %actualfile% to whatever the file name is, instead of pulling it from %0. Beyond that you could use string parsing which seems like overkill. But that's a bit of a tangent.Sizable
@voodoomsr, Okay I have reproduced it. This could be of help: winhelponline.com/blog/…Sizable
@voodoomsr, I have tested the VBScript solution in the link from my above comment, and it works. While it is an added layer of complexity I did not anticipate, you can put the VBS files in the same directory as your BAT files, then from Start > Run.. you can type in myprog.vbs whereas from cmd you can type in myprog. This is still relatively clean and hopefully suits your needs. By the way, the reason I could not reproduce the behavior initially was completely my fault; I actually got interrupted in the middle of testing, and then thought I'd completed a test when I hadn't.Sizable
Your 'edit 4' section is overly complicated for passing arguments to the executable. See Michael Burr's answer.Deutzia
Not sure why this is so upvoted. The original answer and EDITs 2 and 3 present a solution that is simply wrong. EDITs 1 and 4 present an overly complicated and brittle version of a solution that is done properly in other answers. The answerer appears to be almost completely ignorant of the issues raised by the question.Kirstenkirsteni
your solution is very good. however, when I using %var% to replace some part of the directory, when I want to backup the Path environment variable to a text file with command like "set Path>C:\path.txt", the Path will be expand to the full direcotory form, and when the total length is long than 2054 characters, it will be truncated, so do you have any suggest on this export variable excluding by manual.Entertainer
wouldn't creating a bin folder with shortcuts be better than batch files? Specifically because they use less space and can handle arguments the same way as the .exe files.Keil
Edit 4 appeared to work fine at first, but then screwed up a bunch of stuff in my path so that I had to re-ad them. DO NOT USE.Uncovered
D
88

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.

Dulce answered 3/12, 2013 at 22:20 Comment(9)
Thank you that was very useful!! It shortened my path from 1990 to 1338 and everything still works like a charm! I chose your approach because I wanted to keep everything in my path and the linking over batch files would have been too time-consuming. THANKS!Schuster
This was also useful because it told me about all of the non-existent directories in my path that had accumulated over time.Diffusion
Rapid Environment Editor is another way to do this. It highlights non-existent directories and has an option "convert long path to short".Fading
@RussellGallop: that, sir, is an awesome tool.Sapir
Note the missing closing quote after %%~sa. I tried to update the answer but it won't let me unless I change 6 charactersDurrett
I wish I could upvote more than once. I realize this answer came almost 3 years after the "accepted answer" but if I were the OP I would change my mind and make this the accepted answer!Functionalism
One caveat, make sure no one runs fsutil 8dot3name strip anywhere that would affect an abbreviated path name AFTER you use this. Of course, how many people actually knew about fsutil 8dot3name strip before reading this? :-)Functionalism
In addition to this fix, if you have a lot of c:\Program Files and c:\Program Files (x86) entries you can replace them with the variables %ProgramFiles% and %ProgramFiles(x86)% defined at tenforums.com/tutorials/… These only save a few characters each, but if you're REALLY on the verge of maxing out PATH, it could be the difference.Boren
@Boren The 8.3 names of the folders are shorterFunctionalism
S
85

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.

Sizable answered 10/12, 2010 at 2:32 Comment(14)
the 8dot3 form works good, but for directories real big isn't too great, for instance "C:\Program Files (x86)\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Tools\Sandcastle\ProductionTools\". Another thing that save a little was that as a user i could create a PATH variable based in the System Path, and add any other Dir. All of this approaches are of the type "compact that string", but can we have a centralized directory of binaries, as has Unix?Raynard
Hmm, regarding very long directories, I would think the opposite is true: the longer the directory, the more characters you save by using 8dot3 format. If it's hard to navigate in cmd, note that you can use * to save typing. So for example, from root, type in dir /x pro*. You will see your desired directory there along with its 8dot3 name. Then use cd to navigate to it and repeat the process.Sizable
i say that isn't too great in the sense that compressing his length perhaps being a valid solution( that i'm definitely begin to use) don't remove the root problem...having the Path variable overflowed with different directoriesRaynard
Regarding UNIX, there you have $PATH which works very similarly to %PATH% in Windows, so I'm not sure what your point is exactly. By convention, UNIX directory names tend to be shorter than in Windows, and as a result $PATH also tends to be shorter.Sizable
Thanks Mitch, the Edit 4 that you provide is what I wanted!, now i can have centralized folder with all the binaries that i need. I'm going to testing more in deep to see if there is a problem with some appRaynard
hi Mitch i tested in various cases, and the only complain that i have is that for example when you run it from the execute menu, it open a cmd prompt in behind and then open the app that i want,...is there a possibility to hide this prompt?Raynard
@voodoomsr, I cannot reproduce what you described. What version of Windows are you using? Can you give any more details? I did notice while trying to reproduce your results that Windows Vista (32-bit Home Premium SP1) will give the full path along with .bat and quotes as %0 and thus you would need to modify the script accordingly for this use; simplest way (although you lose generality) is to manually set %actualfile% to whatever the file name is, instead of pulling it from %0. Beyond that you could use string parsing which seems like overkill. But that's a bit of a tangent.Sizable
@voodoomsr, Okay I have reproduced it. This could be of help: winhelponline.com/blog/…Sizable
@voodoomsr, I have tested the VBScript solution in the link from my above comment, and it works. While it is an added layer of complexity I did not anticipate, you can put the VBS files in the same directory as your BAT files, then from Start > Run.. you can type in myprog.vbs whereas from cmd you can type in myprog. This is still relatively clean and hopefully suits your needs. By the way, the reason I could not reproduce the behavior initially was completely my fault; I actually got interrupted in the middle of testing, and then thought I'd completed a test when I hadn't.Sizable
Your 'edit 4' section is overly complicated for passing arguments to the executable. See Michael Burr's answer.Deutzia
Not sure why this is so upvoted. The original answer and EDITs 2 and 3 present a solution that is simply wrong. EDITs 1 and 4 present an overly complicated and brittle version of a solution that is done properly in other answers. The answerer appears to be almost completely ignorant of the issues raised by the question.Kirstenkirsteni
your solution is very good. however, when I using %var% to replace some part of the directory, when I want to backup the Path environment variable to a text file with command like "set Path>C:\path.txt", the Path will be expand to the full direcotory form, and when the total length is long than 2054 characters, it will be truncated, so do you have any suggest on this export variable excluding by manual.Entertainer
wouldn't creating a bin folder with shortcuts be better than batch files? Specifically because they use less space and can handle arguments the same way as the .exe files.Keil
Edit 4 appeared to work fine at first, but then screwed up a bunch of stuff in my path so that I had to re-ad them. DO NOT USE.Uncovered
P
29

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.

Pennington answered 9/9, 2014 at 16:14 Comment(3)
This is a nice alternative to using an environment variable to represent a partial path.Expurgatory
This would definitely help more, but if you'd like a more "correct" (supported?) solution, you can replace instances of c:\Program Files and c:\Program Files (x86) with the pre-defined variables %ProgramFiles% and %ProgramFiles(x86)% tenforums.com/tutorials/… These only save a few characters each, but if you're REALLY on the verge of maxing out PATH, it could be the difference. For that matter, I'm going to create %pf% and %pfx% that resolve to the correct paths. Thanks for the idea! :)Boren
The problem with using variables such as %pf% and %pfx% is that you get the same problems as creating symbolic links - software updates may add things again to the path variable. The other problem with using variables like that is that it isn't quick and easy to script things around it or browse to them from explorer. Using the method I described, you can literally open up c:\PF. Windows sees it just like a folder so you can write bat or powershell against it pretty easily too.Pennington
Q
11

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.

Querida answered 10/12, 2010 at 2:19 Comment(0)
C
8

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.

Cladophyll answered 10/12, 2010 at 17:19 Comment(4)
When you start following this "path", beware that a batch script cannot call another batch script without the "CALL [bat]" syntax. So, if you want to make sure your forwarded-or-not exe is called from a bat, use "call php script.php" instead of just "php script.php" (which works both ways) An excellent reason to use .bat dispatcher is to prevent PATH names conflicts (multiples version of the same exe)Uprear
@131: Would you mind explaining what you mean by 'this "path"'? Do you mean the particular file path from the example? Or rather the general method suggested by this answer?Heal
@O.R.Mapper: when 131 says, 'When you start following this "path"', he means, 'When you use this technique'.Cladophyll
As you wrote, "other programs that try to invoke it might not find it properly" - case in point: Unfortunately, it can throw automatic calls to command line applications, for instance by build tools such as NAnt, off course. A remedy is invoking the command with a prepended cmd /c, but that in turn means the build script becomes Windows-specific :/ I've asked about that in a separate question.Heal
C
5

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'.

Caldwell answered 10/12, 2010 at 3:16 Comment(1)
Oops, I just realized this was already suggested by @Mitch. I am going give him a +1 for that. :)Caldwell
P
5

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

Penthouse answered 1/10, 2013 at 10:32 Comment(0)
U
3

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.

Uprear answered 19/8, 2015 at 1:24 Comment(0)
C
1

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"

Caudal answered 10/12, 2010 at 2:29 Comment(1)
I think the path would contain the expanded variables, in which case it wouldn't get any shorter.Overlying
I
0

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.

Irreversible answered 17/5, 2015 at 22:46 Comment(0)
F
0

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.

Fuld answered 11/12, 2015 at 5:7 Comment(0)
I
0

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%
Indebted answered 29/1, 2016 at 19:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.