On Wed, Feb 17, 2016 at 6:53 PM, Dennis Lee Bieber <wlfr...@ix.netcom.com> wrote: > On Wed, 17 Feb 2016 17:49:11 +0000 (UTC), Ulli Horlacher > <frams...@rus.uni-stuttgart.de> declaimed the following: > >>Thorsten Kampe <thors...@thorstenkampe.de> wrote: >> >>> By the way: there is a script called `win_add2path.py` in your Python >>> distribution >> >>I have >>"Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:32:19) [MSC >>v.1500 32 bit (Intel)] on win32" >>and there is no "win_add2path.py" >> > C:\Python_x64\Python27\Tools\scripts\win_add2path.py > > PythonWin 2.7.5 (default, Sep 16 2013, 23:11:01) [MSC v.1500 64 bit > (AMD64)] on win32. > Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' for > further copyright information. > > But I can't confirm that this is not something added in the ActiveState > release.
It's here: https://hg.python.org/cpython/file/v2.7.11/Tools/scripts/win_add2path.py But there are a few issues with this script. * A default value of u"%PATH%" is wrong. That causes the system PATH to be concatenated with itself. * For the user scripts directory, replacing appdata with "%APPDATA%" causes os.path.isdir to always fail. * For QueryValueEx, the only error it should handle is ERROR_FILE_NOT_FOUND. Other OS errors are unlikely, but they shouldn't be masked. * In Python 2, the value returned by QueryValueEx is a unicode string, which this script assumes is ASCII only. So it could die on a UnicodeDecodeError. * REG_EXPAND_SZ should only be used when '%' occurs 2 or more times. Otherwise use REG_SZ. This is important for two-pass environment variable expansion. Thus an existing REG_SZ type should be preserved, if that's reasonable, because the user may be reusing PATH in a REG_EXPAND_SZ variable. * It doesn't broadcast a WM_SETTINGCHANGE message, so it needlessly forces the user to log off and back on in order to use the modified PATH. Here's a new version for Python 2. I generalized the shell-variable replacement to a list of well-known folders. import os import sys import site import ctypes import _winreg import warnings user32 = ctypes.WinDLL('user32', use_last_error=True) HWND_BROADCAST = 0xFFFF WM_SETTINGCHANGE = 0x001A SMTO_ABORTIFHUNG = 0x0002 ERROR_FILE_NOT_FOUND = 0x0002 ERROR_TIMEOUT = 0x05B4 HKCU = _winreg.HKEY_CURRENT_USER ENVIRONMENT = u"Environment" PATH = u"PATH" SCRIPTS = u"Scripts" dir_vars = [u"%APPDATA%", u"%LOCALAPPDATA%", u"%USERPROFILE%", u"%HOMEDRIVE%%HOMEPATH%", u"%ProgramFiles%", u"%ProgramFiles(x86)%"] dir_vals = [_winreg.ExpandEnvironmentStrings(v) for v in dir_vars] def broadcast_change(lparam): if not user32.SendMessageTimeoutW( HWND_BROADCAST, WM_SETTINGCHANGE, 0, ctypes.c_wchar_p(lparam), SMTO_ABORTIFHUNG, 1000, None): err = ctypes.get_last_error() if err != ERROR_TIMEOUT: raise ctypes.WinError(err) def modify(): executable = sys.executable.decode("mbcs") pythonpath = os.path.dirname(os.path.normpath(executable)) scripts = os.path.join(pythonpath, SCRIPTS) if hasattr(site, "USER_SITE"): userpath = site.USER_SITE.decode("mbcs") userscripts = os.path.join(userpath, SCRIPTS) else: userscripts = None with _winreg.CreateKey(HKCU, ENVIRONMENT) as key: try: envpath, dtype = _winreg.QueryValueEx(key, PATH) except WindowsError as e: if e.winerror != ERROR_FILE_NOT_FOUND: raise envpath, dtype = u"", _winreg.REG_EXPAND_SZ if dtype not in (_winreg.REG_SZ, _winreg.REG_EXPAND_SZ): raise TypeError(r"Existing PATH value is not a string.") if dtype == _winreg.REG_SZ and envpath.count(u"%") > 1: warnings.warn('Changing type to REG_EXPAND_SZ.') dtype = _winreg.REG_EXPAND_SZ paths = [envpath] for path in (pythonpath, scripts, userscripts): if path and path not in envpath and os.path.isdir(path): if dtype == _winreg.REG_EXPAND_SZ: for var, val in zip(dir_vars, dir_vals): if val in path: path = path.replace(val, var) break if path in envpath: continue paths.append(path) envpath = os.pathsep.join(paths) _winreg.SetValueEx(key, PATH, 0, dtype, envpath) broadcast_change(ENVIRONMENT) return paths, envpath def main(): paths, envpath = modify() if len(paths) > 1: print "Path(s) added:" print '\n'.join(paths[1:]) else: print "No path was added" print "\nCurrent user PATH is now:\n%s\n" % envpath print "Expanded:" print _winreg.ExpandEnvironmentStrings(envpath) if __name__ == '__main__': main() -- https://mail.python.org/mailman/listinfo/python-list