diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py index 1c9aedc5ed8dca..fd8a2987ba5cf4 100644 --- a/Tools/scripts/win_add2path.py +++ b/Tools/scripts/win_add2path.py @@ -7,47 +7,70 @@ Licensed to PSF under a Contributor Agreement. """ -import sys -import site +import ctypes import os +import site +import sys import winreg HKCU = winreg.HKEY_CURRENT_USER ENV = "Environment" PATH = "PATH" -DEFAULT = "%PATH%" def modify(): pythonpath = os.path.dirname(os.path.normpath(sys.executable)) scripts = os.path.join(pythonpath, "Scripts") appdata = os.environ["APPDATA"] - if hasattr(site, "USER_SITE"): - usersite = site.USER_SITE.replace(appdata, "%APPDATA%") - userpath = os.path.dirname(usersite) - userscripts = os.path.join(userpath, "Scripts") - else: - userscripts = None with winreg.CreateKey(HKCU, ENV) as key: try: - envpath = winreg.QueryValueEx(key, PATH)[0] - except OSError: - envpath = DEFAULT + envpath, dtype = winreg.QueryValueEx(key, PATH) + except FileNotFoundError: + envpath, dtype = "", winreg.REG_EXPAND_SZ + except: + raise OSError("Failed to load PATH value") + + userscripts = None + if hasattr(site, "USER_SITE"): + if dtype == winreg.REG_EXPAND_SZ: + usersite = site.USER_SITE.replace(appdata, "%APPDATA%") + userpath = os.path.dirname(usersite) + userscripts = os.path.join(userpath, "Scripts") + elif dtype == winreg.REG_SZ: + userpath = site.USER_SITE + userscripts = os.path.join(userpath, "Scripts") - paths = [envpath] + paths = [] for path in (pythonpath, scripts, userscripts): - if path and path not in envpath and os.path.isdir(path): + if path and path not in envpath: paths.append(path) - envpath = os.pathsep.join(paths) - winreg.SetValueEx(key, PATH, 0, winreg.REG_EXPAND_SZ, envpath) + if envpath == "": + envpath = os.pathsep.join(paths) + else: + envpath = os.pathsep.join([envpath] + paths) + winreg.SetValueEx(key, PATH, 0, dtype, envpath) return paths, envpath +def refresh_environment_variables(): + HWND_BROADCAST = 0xFFFF + WM_SETTINGCHANGE = 0x001A + SMTO_ABORTIFHUNG = 0x0002 + if not ctypes.windll.user32.SendMessageTimeoutW( + HWND_BROADCAST, + WM_SETTINGCHANGE, + 0, + ENV, + SMTO_ABORTIFHUNG, + 1000): + raise ctypes.WinError() + def main(): paths, envpath = modify() if len(paths) > 1: + refresh_environment_variables() print("Path(s) added:") - print('\n'.join(paths[1:])) + print('\n'.join(paths)) else: print("No path was added") print("\nPATH is now:\n%s\n" % envpath)