32

I have tried below command to append some path to system path variable by batch-file :

setx PATH "%PATH%;C:\Program Files\MySQL\MySQL Server 5.5\bin"

I have checked system variable path after running above batch-file, above path isn't in there.

enter image description here

You can see all windows Variable value content in below :

C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMDAPP\bin\x86;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\ProgramFiles (x86)\ATI Technologies\ATI.ACE\Core-Static;

What am i doing wrong?

Hamed Kamrava
  • 12,359
  • 34
  • 87
  • 125
  • 2
    Use the `/m` switch to add the path to your system path variable instead of your user path variable. See [`setx`](http://ss64.com/nt/setx.html) – David Ruhmann Jun 21 '13 at 20:34
  • 2
    I believe this solution will place a duplicate of the system path into the user's path, as %PATH% expands to system path + user path, i.e. for system path s, user path u, then setx PATH %PATH%;c:\foo will result in user path = s;u;c:\foo, and therefore %PATH%== s;s;u;c:\foo. – Wil S Feb 02 '15 at 21:40
  • In most of the answers the new value is set with `SETX "%PATH%" /m`, but the problem that @Wil S is pointing out is still there if `PATH` has a value in both system path (HKLM) and user path (HKLU). Some programs set the HKLU-PATH when installing. To avoid any duplicates you should get the PATH value with `REG QUERY` and then add your new value. – 244an Jun 24 '15 at 12:17
  • How to access this window from Explorer: _Right click on "This PC" > click on "Properties" > on the left panel of the window that pops up, click on "Advanced system settings" > click on the "advanced" tab > click on "environment variables" button at the bottom of the window._ [via](/questions/17240725/setx-doesnt-append-path-to-system-path-variable#comment103016617_17242476) – cachius May 21 '22 at 21:57

7 Answers7

33

To piggy-back on @Endoro's answer (I lack the rep to comment):

If you want to change the system-wide environment variables, you have to use /M, a la:

setx PATH "%PATH%;C:\Program Files\MySQL\MySQL Server 5.5\bin" /M

setx.exe is picky about placement of the /M, BTW. It needs to be at the end.

mojo
  • 4,050
  • 17
  • 24
  • 13
    Does SETX fail to set more than 1024 characters? When i executed SETX PATH "%PATH%;C:\Temp" it did the job (for 1024 chars) but also warned: The data being saved is truncated to 1024 characters. Any way to get around it? And i **DON'T** want to do make it happen by editing registry. – Harshad Kale Nov 22 '13 at 22:36
  • 1
    Editing the registry isn't bad. The only thing it doesn't do is send the [WM_SETTINGSCHANGE](http://msdn.microsoft.com/en-us/library/windows/desktop/ms725497(v=vs.85).aspx) message. You could always set the registry value then use setx to set/unset some meaningless value. – mojo Nov 23 '13 at 06:13
  • 2
    @kalehv: pretty sure the limitation isn't `setx` per-se in that case. The command line size limits are much more severe on Windows than on Linux, for example. – 0xC0000022L Jan 04 '14 at 00:08
  • I also had to start a new command prompt window before the new path usable. – Hazok Sep 03 '14 at 22:11
  • SETX changes the global environment variable but processes must check to see if it's been updated. CMD.EXE doesn't ever check. To change a variable within CMD, use SET (e.g. `SET "PATH=%PATH%;C:\path\to\bin\dir"`) – mojo Sep 04 '14 at 02:36
20

WARNING!

setx will truncate the value to 1024 characters.

If you use it to modify PATH you might mess up your system.

You can use this PowerShell snippet to add something to your path:

$new_entry = 'c:\blah'

$old_path = [Environment]::GetEnvironmentVariable('path', 'machine');
$new_path = $old_path + ';' + $new_entry
[Environment]::SetEnvironmentVariable('path', $new_path,'Machine');

In case you want to not re-add an already existing entry something like this will do (see for a better version further down):

$new_entry = 'c:\blah'
$search_pattern = ';' + $new_entry.Replace("\","\\")

$old_path = [Environment]::GetEnvironmentVariable('path', 'machine');
$replace_string = ''
$without_entry_path = $old_path -replace $search_pattern, $replace_string
$new_path = $without_entry_path + ';' + $new_entry
[Environment]::SetEnvironmentVariable('path', $new_path,'Machine');

Here a newer version that I'm using now (2017-10-23). This version handles nested paths correctly. E.g. it handles the case of PATH containing "c:\tool\foo" and you want to add "c:\tool".

Note, that this expands values that are in path and saves them back expanded. If you want to avoid this, have a look at the comment of @ErykSun below.

$desired_entry = 'C:\test'

$old_path = [Environment]::GetEnvironmentVariable('path', 'machine');

$old_path_entry_list = ($old_path).split(";")
$new_path_entry_list = new-object system.collections.arraylist

foreach($old_path_entry in $old_path_entry_list) {
    if($old_path_entry -eq $desired_entry){
        # ignore old entry
    }else{
        [void]$new_path_entry_list.Add($old_path_entry)
    }
}
[void]$new_path_entry_list.Add($desired_entry)
$new_path = $new_path_entry_list -Join ";"

[Environment]::SetEnvironmentVariable('path', $new_path,'Machine');
Robert Fey
  • 1,747
  • 22
  • 23
  • What do i have to use for the variable `machine`? Is it the name of my computer? – surfmuggle Dec 02 '16 at 12:36
  • 'machine' is a constant string and not a variable. – Robert Fey Dec 02 '16 at 17:00
  • 3
    The raw "Path" value in the registry usually depends on other system variables (e.g. `%SystemRoot%`) and other independent values in the system environment. (A `REG_SZ` value doesn't depend on other variables, unlike a `REG_EXPAND_SZ` value. `REG_SZ` values are loaded first when reloading the environment, so they're safe to use in `PATH`.) Unfortunately `GetEnvironmentVariable` expands them and thus loses useful information. This gets the raw system value: `(get-item "HKLM:\System\CurrentControlSet\Control\Session Manager\Environment").GetValue("PATH", $null, "DoNotExpandEnvironmentNames")`. – Eryk Sun Feb 02 '20 at 16:05
  • @ErykSun Do you have a working PS1 script that uses your modification and doesn't expand path values? – fmotion1 Oct 21 '21 at 08:35
  • 1
    the correct constant to use is `[System.EnvironmentVariableTarget]::Machine` instead of `'machine'` although I think it is much better practice to use `[System.EnvironmentVariableTarget]::User` – Dmytro Bugayev Dec 12 '22 at 00:40
7

you shouldn't look at the system environment variables but to your user environment variables:

enter image description here

Endoro
  • 37,015
  • 8
  • 50
  • 63
  • How do you get to that window? – Reversed Engineer Jun 27 '19 at 13:50
  • 1
    @ReversedEngineer Right click on "This PC" > click on "Properties" > on the left panel of the window that pops up, click on "Advanced system settings" > click on the "advanced" tab > click on "environment variables" button at the bottom of the window. – Peter Cheng Oct 10 '19 at 18:45
6

Should never use setx for a path since it's limited to 1024 chars, as mentioned.

Could use reg add:

set pathkey="HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment"
for /F "usebackq skip=2 tokens=2*" %%A IN (`reg query %pathkey% /v Path`) do (reg add %pathkey% /f /v Path /t REG_SZ /d "%%B;C:\Program Files\MySQL\MySQL Server 5.5\bin")

or set pathkey="HKEY_CURRENT_USER\Environment" for user path.

Then to broadcast the change:

powershell -command "& {$md=\"[DllImport(`\"user32.dll\"\",SetLastError=true,CharSet=CharSet.Auto)]public static extern IntPtr SendMessageTimeout(IntPtr hWnd,uint Msg,UIntPtr wParam,string lParam,uint fuFlags,uint uTimeout,out UIntPtr lpdwResult);\"; $sm=Add-Type -MemberDefinition $md -Name NativeMethods -Namespace Win32 -PassThru;$result=[uintptr]::zero;$sm::SendMessageTimeout(0xffff,0x001A,[uintptr]::Zero,\"Environment\",2,5000,[ref]$result)}"
colin lamarre
  • 1,714
  • 1
  • 18
  • 25
5
SETX /M Path "%PATH%;%ProgramFiles%\MySQL\MySQL Server 5.5\bin\

It will append your path to system variable

Hamed Kamrava
  • 12,359
  • 34
  • 87
  • 125
chiragchavda.ks
  • 532
  • 7
  • 25
1

To update and expand on Endoro's answer for Windows 10, manually add the path to your Path system variable as a new variable. I wasn't able to get setx to work even changing the flags around. Doing it manually was simple.

To get to your system environmental variables -> Windows Key -> Edit the system environmental variables -> Click Environmental Variables -> Select the Path variable in the System variables frame -> Click Edit -> Click New -> Add the path -> Click Okay

Make sure you close all your CLI windows and open a new one if you're trying to verify by checking the version.

Windows showing where to edit the Path environmental variable

0

I faced the same problem when I tried to add path variables related to fortran. (Eclipse for C/C++/Fortran)

I tried SETX /M Path "%PATH%;C:\Users\mahidhai\cygwin64\bin" in command prompt as administrator. I got a warning saying data was truncated to 1024 characters and stored.

Edit registry via GUI
  • Run->regedit
  • Navigate to HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
    • HKLM is short for HKEY_LOCAL_MACHINE
  • Doubleclick on the Path entry or invoke value edit mode via context menu
  • Append the parent directory of your exe separated by a semicolon ;
  • Refresh the registry changes to the system

No worries on editing the registry, it is safe as long as you don't change random values.

Though if using a GUI you should use the purpose built one.

Edit via purpose built GUI starting in Explorer
  1. Right click on "This PC"
  2. Click on "Properties"
  3. On the left panel of the window that pops up, click on "Advanced System Settings"
  4. Click on the "Advanced" tab
  5. Click on "Environment Variables" button at the bottom of the window

Environment Variables managment window of Windows

Image from this answer

cachius
  • 1,743
  • 1
  • 8
  • 21
V SAI MAHIDHAR
  • 167
  • 1
  • 7