Skip to content

Instantly share code, notes, and snippets.

Created December 1, 2014 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/fb5d176ab91dccbd0ebd to your computer and use it in GitHub Desktop.
Save anonymous/fb5d176ab91dccbd0ebd to your computer and use it in GitHub Desktop.
Fixes python's PATH entries on Windows. Run as Administrator.
# coding: utf-8
'''
Fixes python's PATH entries on Windows. Run as Administrator.
https://stackoverflow.com/users/1307905/anthon
fixed by https://stackoverflow.com/users/19993/aur-saraf
'''
import sys
import os
import time
import _winreg
import ctypes
def find_python():
"""
retrieves the commandline for .py extensions from the registry
"""
hKey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
r'Python.File\shell\open\command')
# get the default value
value, typ = _winreg.QueryValueEx (hKey, None)
program = value.split('"')[1]
if not program.lower().endswith(r'\python.exe'):
return None
return os.path.dirname(program)
def extend_path(pypath, remove=False, verbose=0, script=False):
"""
extend(pypath) adds pypath to the PATH env. variable as defined in the
registry, and then notifies applications (e.g. the desktop) of this change.
!!! Already opened DOS-Command prompts are not updated. !!!
Newly opened prompts will have the new path (inherited from the
updated windows explorer desktop)
options:
remove (default unset), remove from PATH instead of extend PATH
script (default unset), try to add/remove the Scripts subdirectory
of pypath (pip, easy_install) as well
"""
_sd = 'Scripts' # scripts subdir
scriptspath = os.path.join(pypath, _sd)
hKey = _winreg.OpenKey (_winreg.HKEY_LOCAL_MACHINE,
r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
0, _winreg.KEY_READ | _winreg.KEY_SET_VALUE)
value, typ = _winreg.QueryValueEx (hKey, "PATH")
vals = value.split(';')
assert isinstance(vals, list)
lowervals = value.lower().split(';')
def already_exists(v):
v = v.lower()
for val in lowervals:
if val in [v, v + os.path.pathsep]:
return True
return False
if remove:
try:
vals.remove(pypath)
except ValueError:
if verbose > 0:
print 'path element', pypath, 'not found'
return
if script:
try:
vals.remove(scriptspath)
except ValueError:
pass
print 'removing from PATH:', pypath
else:
if not already_exists(pypath):
if verbose > 0:
print 'path element', pypath, 'already in PATH'
else:
vals.append(pypath)
if verbose > 1:
print 'adding to PATH:', pypath
if script:
if not already_exists(scriptspath):
vals.append(scriptspath)
if verbose > 1:
print 'adding to PATH:', scriptspath
return
_winreg.SetValueEx(hKey, "OLDPATH", 0, typ, value )
_winreg.SetValueEx(hKey, "PATH", 0, typ, ';'.join(vals) )
_winreg.FlushKey(hKey)
# notify other programs
SendMessage = ctypes.windll.user32.SendMessageW
HWND_BROADCAST = 0xFFFF
WM_SETTINGCHANGE = 0x1A
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, u'Environment')
if verbose > 1:
print 'Do not forget to restart any command prompts'
if __name__ == '__main__':
remove = '--remove' in sys.argv
script = '--noscripts' not in sys.argv
extend_path(find_python(), verbose=2, remove=remove, script=script)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment