You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.1 KiB

7 years ago
7 years ago
  1. from winreg import *
  2. import argparse
  3. import win32con
  4. import win32gui
  5. import re
  6. import itertools
  7. user = 'Environment'
  8. system = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
  9. class regkey(object):
  10. def __init__(self,root, path):
  11. self.path = path
  12. self.root = root
  13. reg = ConnectRegistry(None, root)
  14. self.key = OpenKey(reg, path, 0, KEY_ALL_ACCESS)
  15. def set_value(self, name, value,t=REG_EXPAND_SZ):
  16. SetValueEx(self.key, name, 0, t, value)
  17. win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')
  18. def get_value(self, name, ret_type = False):
  19. value, type_id = QueryValueEx(self.key, name)
  20. if ret_type:
  21. return value, type_id
  22. else:
  23. return value
  24. class path_key(regkey):
  25. def __init__(self,root=HKEY_CURRENT_USER, path=user):
  26. super(path_key,self).__init__(root,path)
  27. self.path_set = self.get_path_setobj()
  28. def get_path_setobj(self):
  29. path = self.get_value('Path')
  30. path = set(path.split(';'))
  31. return path
  32. def format_path(self):
  33. path = self.path_set
  34. return ';'.join(sorted(path))
  35. def add(self, path):
  36. self.path_set.add(path)
  37. def remove(self, path):
  38. self.path_set.discard(path)
  39. def commit(self):
  40. path = self.format_path()
  41. self.set_value('Path', path)
  42. def check(self,path):
  43. return path in self.path_set
  44. def search_remove(pathobj,pattern,action,regex=False,negate=False,dry_run=False):
  45. if negate:
  46. flt = itertools.filterfalse
  47. else:
  48. flt = filter
  49. if regex:
  50. pattern = re.compile(pattern,re.IGNORECASE)
  51. results = flt(lambda path: pattern.search(path),pathobj.path_set)
  52. else:
  53. pattern = pattern.lower()
  54. results = flt(lambda path: pattern in path.lower(),pathobj.path_set)
  55. for path in list(results):
  56. if dry_run:
  57. print('REM: {path}'.format(path=path))
  58. else:
  59. action(path)
  60. if __name__ == "__main__":
  61. parser = argparse.ArgumentParser(prog='path')
  62. parser.add_argument('-l','--list',action = 'store_true',help = 'list path entries')
  63. parser.add_argument('-s','--system',action = 'store_true',help = 'use system enviroment instead of current user')
  64. alts = parser.add_subparsers(dest='command')
  65. mod = alts.add_parser('mod')
  66. group = mod.add_mutually_exclusive_group(required=True)
  67. group.add_argument('-a', dest='add', action= 'store_true', help='add to PATH')
  68. group.add_argument('-r', dest='remove', action ='store_true', help='remove from PATH')
  69. mod.add_argument('-d',dest='dry_run',action='store_true',help='dry run')
  70. mod.add_argument('path', help = 'Path to be appended to PATH')
  71. rem = alts.add_parser('rem')
  72. rem.add_argument('--regex',action='store_true',help='use regex')
  73. rem.add_argument('-n',action = 'store_true',help = 'negate pattern')
  74. rem.add_argument('-d',dest='dry_run',action='store_true',help='dry run')
  75. rem.add_argument('pattern', help = 'pattern to search through path and remove matches')
  76. args = parser.parse_args()
  77. if args.system:
  78. try:
  79. path = path_key(HKEY_LOCAL_MACHINE,system)
  80. except PermissionError:
  81. print('Must be admin to view system keys')
  82. exit()
  83. else:
  84. path = path_key()
  85. if args.list:
  86. print('\n'.join(sorted(path.path_set)))
  87. elif args.command == 'mod':
  88. if args.dry_run:
  89. if args.add:
  90. print('ADD: {path}'.format(path=args.path))
  91. else:
  92. assert(path.check(args.path))
  93. print('REM: {path}'.format(path=args.path))
  94. else:
  95. if args.add:
  96. path.add(args.path)
  97. else:
  98. assert(path.check(args.path))
  99. path.remove(args.path)
  100. path.commit()
  101. elif args.command == 'map':
  102. search_remove(path,args.pattern,path.remove,args.regex,args.n,args.dry_run)
  103. if not args.dry_run:
  104. path.commit()
  105. else:
  106. parser.parse_args(['-h'])