101

I am trying to set environment variables using the setx command, such as follows

setx PATH "f:\common tools\git\bin;f:\common tools\python\app;f:\common tools\python\app\scripts;f:\common tools\ruby\bin;f:\masm32\bin;F:\Borland\BCC55\Bin;%PATH%"

However, I get the following error if the value is more then 1024 characters long:

WARNING: The data being saved is truncated to 1024 characters.

SUCCESS: Specified value was saved.

But some of the paths in the end are not saved in variable, I guess due to character limit as the error suggests.

Madhur Ahuja
  • 1,969

11 Answers11

65

Your best bet is to edit the registry directly.

Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and edit the Path value (then reboot to activate the new value).

Note however that while you can enter a very long path, (up to the maximum environment variable length; 2,048 or 32,768 bytes depending on the source), not all software will be able to read and handle it correctly if it is too long.

Synetech
  • 69,547
37

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"
mklink /d C:\pf86 "C:\Program Files (x86)"

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.

(I know it's not related to setx but it is useful for people which are searching overcomming on 1024 char limit)

Reza
  • 743
29

You could use a PowerShell script similar to the following:

$newPath = 'F:\common tools\git\bin;F:\common tools\python\app;F:\common tools\python\app\scripts;F:\common tools\ruby\bin;F:\masm32\bin;F:\Borland\BCC55\Bin'
$oldPath = [Environment]::GetEnvironmentVariable('PATH', 'Machine');
[Environment]::SetEnvironmentVariable('PATH', "$newPath;$oldPath",'Machine');

The Environment.SetEnvironmentVariable() API call will broadcast WM_SETTINGCHANGE so you do not need to reboot.

7

This open-source SetEnv command-line tool is good to edit the PATH and other environment variables without limitations. It uses a dynamic buffer so no static limitations like 1024.

http://www.codeproject.com/Articles/12153/SetEnv

The choice of a % as a prefix to append to a variable could have been better though, as makes the syntax difficult sometimes if used with other batch local variables...

4

A far superior tool than setx for path manipulation is pathed.exe. Unfortunately, it's limited to editing the path.

In addition to a superior user experience than setx, you don't have a 1024 character limit. Unlike direct registry manipulation, this application uses the Environment.SetEnvironmentVariable() API call which will broadcast WM_SETTINGCHANGE.

3

You can put this line in your BAT:

setx path "%%path%%;c:\drive\fr;c:\drive\installs\7z"

See the double %%.

(Reference: https://support.microsoft.com/en-us/kb/75634)

2

My favorite way is to change the folder names in the PATH variables to use the 8.3 names. This StackOverflow answer has an awesome script (run from a .bat file) that will generate the "minified" version of the entire PATH variable, which you can then paste into the Edit Variable dialog(s). Only caveat is that you will need to split out the SYSTEM and USER parts. As the script goes through and figures out the minified version for each folder, it discards and alerts you of any invalid/non-existent paths. Nice little clean up bonus.

1

A new tool is born, it works very well, have unique features and solve all setx problems: regenv

  • it works in xp+.

  • it is better than setx ,pathed, pathman, setenv

  • it is a fork of the old nice setenv tool

set "var=D:\Bin"

REM ::::: override a system var: regenv.exe set -nS c "%var%"

REM ::::: append to a system var regenv.exe set -nS -sa c "%var%"

REM ::::: preppend to a system var regenv.exe set -nS -sp c "%var%"

REM ::::: create a variable that contains an unexpanded variable regenv.exe set -nS -sp c "%%var%%"

REM ::::: edit PATH: if you edit PATH it is good to use -x , because -x will convert the reg type from REG_SZ to REG_EXPAND_SZ, because some tools may create a REG_SZ while the default reg type for PATH is/should be REG_EXPAND_SZ regenv.exe set -nS -sp -x PATH "%var%"

NB: if var contain a backslash at the end, use double backlash:

regenv.exe set -nS c "D:\Bin\\"
REM gaves D:\Bin\

or delete the last backslash:

set "var=D:\Bin\"
REM -- Great example from Strawberry Perl's portable shell launcher:  this deletes the final backslash \.
if #%var:~-1%# == #\# set var=%var:~0,-1%
regenv.exe set -nS c "%var%"
:: gaves D:\Bin

it can even create Volatile variables (HKCU\Volatile Environment).

it is really a nice work.

0

I think the best way is the next (with powershell) With this way also you avoid the litmit of 1024 character.

You can see the code on: https://gist.github.com/drazul/b92f780689bd89a0d2a7

#------------ Add path to system variable -------------------------------------

$path2add = ';C:\path;'
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

If (!$systemPath.contains($path2add)) {
    $systemPath += $path2add
    $systemPath = $systemPath -join ';'
    [Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');
    write-host "Added to path!"
    write-host $systemPath
}

#------------ Delete path from system variable --------------------------------

$path2delete = 'C:\path;'
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

$systemPath = $systemPath.replace($path2delete, '')
$systemPath = $systemPath -join ';'

[Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');

write-host "Deleted from path!"
write-host $systemPath

#------------ Clean system variable -------------------------------------------

$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

while ($systemPath.contains(';;')) {
    $systemPath = $systemPath.replace(';;', ';')
}

[Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');

write-host "Cleaned path!"
write-host $systemPath
Drazul
  • 101
0

Just a little ready-to-use packing of the Powershell version . Save this as a .cmd or .bat, UTF-8 or ASCII text file . Remember to restart programs that were running during the change .

@echo off
set br=^

rem br; pushd "%~dp0" &rem Working/{temp files} Directory . pat>->paf ; setlocal enableExtensions enableDelayedExpansion

rem # Required : rem Windows Powershell v1.0 by Microsoft . rem # ;

echo Make sure to run this as Administrator .!br! pause echo( set v=

set /p v=Enter the items to add . Separate by, and end the list with ";" . Do not use quotes .!br!!br!& rem #optional

rem set v=C:\Windows\WinSxS;!v! &rem MSBuild ; #optional

"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -Command "[Environment]::SetEnvironmentVariable('Path',"%v%$([Environment]::GetEnvironmentVariable('Path','Machine'))",'Machine');" &rem Windows Powershell by Microsoft ;

:sc_n rem endlocal rem popd pause rem exit /b

irvnriir
  • 125
-2

if it is not required to keep system PATH and user PATH separate:

::setx /m truncate variable length to 1024 REG ADD 
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_SZ /f /d "%PATH%"
::empty local path, use system wide only, else it will enlarge with every setx /m
setx PATH ""
::setx is dummy but propagate system wide variables with it
setx /m A A