Skip to content

Instantly share code, notes, and snippets.

@roblogic
Created November 21, 2016 01:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save roblogic/59898966f3ce594eb78a5b6147013194 to your computer and use it in GitHub Desktop.
Save roblogic/59898966f3ce594eb78a5b6147013194 to your computer and use it in GitHub Desktop.
Editing Windows PATH with AutoHotKey
#SingleInstance, Force
#NoEnv ; somewhat ironic...
; this won't work in vista/7 if it's not run as an administrator.
; i'm too lazy to request it manually so the easiest way is to
; compile this script, and then under Compatibility tab in the
; compiled exe's Properties select "Run as Administrator"
RegRead, P, HKLM, SYSTEM\CurrentControlSet\Control\Session Manager\Environment, PATH
Gui, +Delimiter`;
width := 400
Gui, Add, Text, w%width%, Double Click an entry to modify it. Click Add to make a new entry and Delete to remove the selected entry.
Gui, Add, ListBox, vSysPath w%width% r8 +0x100 gEditEntry AltSubmit, %P%
Gui, Font, s12
Gui, Add, Button, gNew w70 section , New
Gui, Add, Button, gDelete w70 ys xs+74 , Delete
Gui, Add, Button, gExit w70 ys xs+330, Cancel
Gui, Add, Button, gSubmit w70 ys xp-74, Submit
Gui, Show, , SysEnv -- Change System Environment Variable
return
EditEntry:
if (a_guievent == "DoubleClick" && a_eventinfo) {
Gui +OwnDialogs
RegExMatch(P, "P)^(?:(?<E>[^;]*)(?:;|$)){" a_eventinfo "}", _)
_En := IB( "Edit PATH entry", substr(P, _PosE, _LenE))
if (ErrorLevel == 0)
{
if (InStr(FileExist(ExpEnv(_En)),"D"))
{
rP := substr(P, 1, _PosE-1) _En (_PosE+_LenE+1 < strlen(P) ? ";" substr(P, _PosE+_LenE+1) : "")
P := rP
GuiControl, , SysPath, `;%P%
}
else
MsgBox, , SysEnv, Path is not a directory.
}
}
return
New:
add := IB( "Add PATH entry" )
if (instr(fileexist(ExpEnv(add)),"D")) {
P .= (strlen(P) > 0 ? ";" : "") add
GuiControl, , SysPath, `;%P%
}
return
Delete:
GuiControlGet, entry, , SysPath
if (entry) {
Gui, +OwnDialogs
MsgBox, 4, SysEnv -- Confirm, Remove entry #%entry% from PATH?
IfMsgBox Yes
{
RegExMatch(P, "P)^(?:(?<E>[^;]*)(?:;|$)){" entry "}", _)
P := SubStr(P, 1, max(_PosE-2,0)) (_PosE+_LenE+1 < strlen(P) ? ";" substr(P, _PosE+_LenE+1) : "")
GuiControl, , SysPath, `;%P%
}
}
return
Submit:
Gui, +OwnDialogs
MsgBox, 1, SysEnv -- Save Changes, Change system PATH to:`n`n%P%
IfMsgBox, OK
{
RegWrite, REG_EXPAND_SZ, HKLM, SYSTEM\CurrentControlSet\Control\Session Manager\Environment, PATH, %P%
If !ErrorLevel
{
;WM_SETTINGCHANGE = 0x1A
;See HWND_BROADCAST in
;http://www.autohotkey.com/docs/commands/PostMessage.htm
SendMessage, 0x1A,0,"Environment",, ahk_id 0xFFFF
MsgBox, 0, SysEnv -- Success!, Modifying the PATH variable was successful!
}
Else
MsgBox, , SysEnv, Error has occurred and new PATH variable was not saved.
}
Else
MsgBox, , SysEnv -- Cancelled, Exiting now.
Exit:
GuiClose:
GuiEscape:
GuiEsc:
ExitApp
IB( prompt, default="" ) {
InputBox, out, SysEnv -- %prompt%, %prompt%:, , , , , , , , %default%
return out
}
max( a, b ) {
return a > b ? a : b
}
ExpEnv(str) {
; by Lexikos: http://www.autohotkey.com/forum/viewtopic.php?p=327849#327849
if sz:=DllCall("ExpandEnvironmentStrings", "uint", &str, "uint", 0, "uint", 0)
{
VarSetCapacity(dst, A_IsUnicode ? sz*2:sz)
if DllCall("ExpandEnvironmentStrings", "uint", &str, "str", dst, "uint", sz)
return dst
}
return ""
}
@roblogic
Copy link
Author

roblogic commented Nov 21, 2016

Verified working on Windows 7 Pro.

image2015-11-30 15-46-32-ahk

@tallpeak
Copy link

tallpeak commented Mar 7, 2022

Cool! My path is 3k+ (over the 2048 limit) so Windows11's environment editor refuses to save changes, whereas your script works. (I presume.) I tried adding EnvUpdate, but I guess I still need a reboot.

@roblogic
Copy link
Author

Thanks, I have no idea if it still works. Over 2048 characters is a looong path! Probably better to create a symlink to the target then add that to the PATH variable.
https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/

@chaoscreater
Copy link

This doesn't help. You can add stuff to PATH but the PATH variable will not actually load anything past a certain limit.

If you run $env:PATH in Powershell, it gets cut off at a certain point. If you try to populate the PATH variable with e.g. 5000 entries and you run where.exe git or whatever, it won't be able to find the exe binary, even though the path is added to PATH.

You can also simply backup the PATH registry key and edit the registry key, then import it. But the problem remains.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment