From ddaf7aab2baf4827bb92659181a1911bebf734cd Mon Sep 17 00:00:00 2001 From: neEverett Date: Thu, 18 May 2017 15:46:58 +0800 Subject: [PATCH 1/3] fix several bugs * Discard the DEFAULT "%PATH%" value. * Delete wrong `os.path.isdir()`. * Add absolute path instead of `%APPDATA%...` if the type of PATH is `REG_SZ`. * Broadcast a `WM_SETTINGCHANG` message after the change of env vars. * Add codes to deal with possible errors. --- Tools/scripts/win_add2path.py | 54 +++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py index 1c9aedc5ed8dca..9340bea88e8c7f 100644 --- a/Tools/scripts/win_add2path.py +++ b/Tools/scripts/win_add2path.py @@ -11,43 +11,67 @@ import site import os import winreg +import ctypes 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 + pass + except: + raise OSError("Failed to load PATH value") + + if hasattr(site, "USER_SITE") and 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") + else: + userscripts = None - 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) From 0cdb0e848b26330e54c12a4119377c0f498b3a25 Mon Sep 17 00:00:00 2001 From: neEverett Date: Mon, 4 Feb 2019 11:42:21 +0000 Subject: [PATCH 2/3] Tie up some loose ends Fixed the problems mentioned here: https://github.com/python/cpython/pull/1645 --- Tools/scripts/win_add2path.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py index 9340bea88e8c7f..1eeef3a0bed3e4 100644 --- a/Tools/scripts/win_add2path.py +++ b/Tools/scripts/win_add2path.py @@ -7,11 +7,11 @@ Licensed to PSF under a Contributor Agreement. """ -import sys -import site +import ctypes import os +import site +import sys import winreg -import ctypes HKCU = winreg.HKEY_CURRENT_USER ENV = "Environment" @@ -27,19 +27,18 @@ def modify(): envpath, dtype = winreg.QueryValueEx(key, PATH) except FileNotFoundError: envpath, dtype = "", winreg.REG_EXPAND_SZ - pass except: raise OSError("Failed to load PATH value") - if hasattr(site, "USER_SITE") and 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") - else: - userscripts = None + 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 = [] for path in (pythonpath, scripts, userscripts): From 80e887455dda08c938a773470636e19ddf632edf Mon Sep 17 00:00:00 2001 From: neEverett Date: Mon, 4 Feb 2019 11:46:53 +0000 Subject: [PATCH 3/3] Tie up some loose ends Fixed the problems mentioned here: https://github.com/python/cpython/pull/1645 --- Tools/scripts/win_add2path.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py index 1eeef3a0bed3e4..fd8a2987ba5cf4 100644 --- a/Tools/scripts/win_add2path.py +++ b/Tools/scripts/win_add2path.py @@ -30,10 +30,10 @@ def modify(): except: raise OSError("Failed to load PATH value") - userscripts = None + userscripts = None if hasattr(site, "USER_SITE"): if dtype == winreg.REG_EXPAND_SZ: - usersite = site.USER_SITE.replace(appdata, "%APPDATA%") + usersite = site.USER_SITE.replace(appdata, "%APPDATA%") userpath = os.path.dirname(usersite) userscripts = os.path.join(userpath, "Scripts") elif dtype == winreg.REG_SZ: