Windows下如何体面的修改环境变量

admin 2021年5月29日05:20:40评论327 views字数 5157阅读17分11秒阅读模式

本文最终输出了一个【系统环境变量修改】工具,
用于方便快捷有效的操作windows系统环境变量,
setenv.exe提供增加,修改,查询功能。


△△△点击上方“蓝字”关注我们了解更多精彩




0x00 Preface [前言/简介]

昨天环境变量出了一点问题,我知道强迫症不能再逃避了。

以前写过一章节来制作Win下各语言的便携环境。

第1章-重构1-Win下各语言便携环境制作

第1章-重构2-Win下各语言便携环境分享


主要是个步骤:

1、获取免安装版本

2、加入Path环境变量,便于命令行调用

3、加入注册表,便于图形化调用(大部分情况不需要)


对于其中1.获取免安装的版本,倒是很简单的事情,无论是直接下载官方提供的zip,又或者是自己从安装文件夹中进行提取。


对于其中3.加入注册表,我也写好了一个通用的reg模板,只要修改文件位置就行。


唯有其中的2.加入path环境变量的快捷脚本,随着日常的使用变得有些问题。



0x01 Path环境变量过长的问题

由于电脑中存在多种语言的环境变量,导致Path环境变量过长,

直接运行设置环境变量的bat时会提示path环境变量过长,在1024字符处截断,从而导致没有备份的情况下,使得注册表变得损坏。


查询资料发现网上的方案有三个:


1,将需要加入Path的环境变量,通过mlink命令创建一个硬链接,加入到一个已存在的path的目录下,如C:\windows目录下。

2,新建一个path1环境变量,将需要加入Path的环境变量,加入path1变量中,再将%path1%加入到path环境变量中。


3,直接通过注册表修改环境变量的值。





0x02 解决方案测试
1、经过测试发现方法1比较麻烦,且不便于管理,遂放弃

2、原则上方法二可以满足需求,但经过测试发现方法2的情况下,在中文路径下调用命令(例如python.exe)会失败,原因暂未找到。

3、最终只能选择使用直接修改注册表的方式来修改windows的环境变量。

如果直接使用reg操作注册表,太过于繁杂,所以尝试使用python对注册表进行操作,最终能够输出一个代替setx.exe的工具,来设置我的环境变量。




0x03 setenv工具实现
有了思路,尝试在百度上进行相关库的查找,
最终发现,python的winreg模块支持在windows下进行注册表操作。
且博客园中已有较好的函数实现思路。
python通过操作windows系统注册表方式修改环境变量 - slqt - 博客园https://www.cnblogs.com/slqt/p/5718154.html
对其进行精简和优化,再加上实践上的修复,最终实现代码如下:
#coding=utf8#python3 OKimport osimport sysimport subprocesstry:    import win32api, win32conexcept ImportError:    os.system('pip3 install pywin32 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com')    print('please run again !!!')if sys.hexversion > 0x03000000:    import winregelse:    import _winreg as winreg
#指定修改的时系统环境变量的注册表键值root = winreg.HKEY_LOCAL_MACHINEsubkey = r'SYSTEMCurrentControlSetControlSession ManagerEnvironment'
def get_env(name):#系统环境变量获取 key = winreg.OpenKey(root, subkey, 0, winreg.KEY_READ)try: value, _ = winreg.QueryValueEx(key, name)except WindowsError: value = ''#print(value)return value
def set_env(name, value):#系统环境变量设置# Note: for 'system' scope, you must run this as Administrator key = winreg.OpenKey(root, subkey, 0, winreg.KEY_ALL_ACCESS) winreg.SetValueEx(key, name, 0, winreg.REG_EXPAND_SZ, value) winreg.CloseKey(key)# For some strange reason, calling SendMessage from the current process# doesn't propagate environment changes at all.# TODO: handle CalledProcessError (for assert) subprocess.check_call('''"%s" -c "import win32api, win32con;assert win32api.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE,0, 'Environment')"''' % sys.executable)
def add_env(name, value):#系统环境变量增加# Note: for 'system' scope, you must run this as Administrator env_lib = get_env(name)#判断环境变量是否存在,存在的话使用追加,不存在的话使用新建if env_lib != '' :#print('The variable [%s] was exist' % name)#判断值是否已存在于变量,存在的话进行替换操作然后追加,不存在的话使用新建if value+';' in env_lib:#print('The value [%s] variable was exist' % value) set_env(name,(value +';'+ env_lib.replace(value+';','')))else:#print('The value [%s] variable not exist' % value) set_env(name,value+';'+env_lib)else: print('The variable [%s] not exist' % name) set_env(name, value)
def dup_env(name):#系统环境变量去重# Note: for 'system' scope, you must run this as Administrator env_lib = get_env(name)#判断环境变量是否存在,存在的话进行拆分和合并,不存在的话忽略if env_lib != '' :#print('The variable [%s] was exist' % name) env_lib = env_lib.replace(';;',';').replace('\;',';').strip('\') env_lib_list = env_lib.split(';')#列表去空 env_lib_list = [i for i in env_lib_list if i != '']#列表去重 env_lib_new = []for i in env_lib_list:if i not in env_lib_new: env_lib_new.append(i) env_lib = ';'.join('%s' % i for i in env_lib_new)#print('de-weight env_lib_new',env_lib_new) set_env(name, env_lib)else: print('The variable [%s] not exist' % name)
def rank_env(name):#系统环境变量去重# Note: for 'system' scope, you must run this as Administrator env_lib = get_env(name)#判断环境变量是否存在,存在的话进行拆分和合并,不存在的话忽略if env_lib != '' :#print('The variable [%s] was exist' % name) env_lib = env_lib.replace(';;',';').replace('\;',';').strip('\') env_lib_list = env_lib.split(';')#列表去空 env_lib_list = [i for i in env_lib_list if i != '']#列表去重 env_lib_new = []for i in env_lib_list:if i not in env_lib_new: env_lib_new.append(i) env_lib_new.sort()#print(env_lib_new) env_lib = ';'.join('%s' % i for i in env_lib_new) set_env(name, env_lib)else: print('The variable [%s] not exist' % name)
if __name__=='__main__': usage="""请使用管理员权限运行!!!查询、追加设置、覆盖设置、去杂 指定环境变量!!!scrpt_name -g 环境变量名称scrpt_name -a 环境变量名称 环境变量的值scrpt_name -s 环境变量名称 环境变量的值scrpt_name -d 环境变量名称 (原顺)scrpt_name -r 环境变量名称 (排顺)""".replace('scrpt_name',sys.argv[0].rsplit('\',1)[-1]).strip()
if len(sys.argv) > 2: name = sys.argv[2]if sys.argv[1]== '-g' : print(get_env(name))elif sys.argv[1]== '-a' : value = sys.argv[3] add_env(name,value) print(get_env(name))elif sys.argv[1]== '-d' : dup_env(name) print(get_env(name))elif sys.argv[1]== '-s' : value = sys.argv[3] set_env(name,value) print(get_env(name))elif sys.argv[1]== '-r' : rank_env(name) print(get_env(name))else: print(usage)



0x05 setenv工具使用

写该工具的目的是为了设置python等环境的环境变量,
如果当前本机没有python环境变量该如何?
遂对脚本在win10x86主机中进行了pyinstaller打包(文末下载)

λ setenv.exe -h['setenv.exe', '-h']请使用管理员权限运行!!!查询、追加设置、覆盖设置、去杂 指定环境变量!!!setenv.exe -g 环境变量名称setenv.exe -a 环境变量名称 环境变量的值setenv.exe -s 环境变量名称 环境变量的值setenv.exe -d 环境变量名称(原顺)  setenv.exe -r 环境变量名称(排顺)
-g get_env通过注册表查询系统环境变量的值。
-s set_env设置一个系统环境变量的值。例:-a test 111 会使test环境变量变成111
-a add_env追加设置一个环境变量的值,会追加值到前面。例:-a path 111 会使path环境变量变成111;path原来的的值
-d dup_env 将优化去重指定的环境变量,去重后不改变默认的顺序-r rank_env 将优化去重指定的环境变量,按去重后会进行排序例:-d path  会去重path环境变量例:-r path 会去重path环境变量,并将环境变量进行排序



0x09 Summary 总结
1、请偶尔备份环境变量。
2、不要再使用bat来设置path环境变量

公众号后台回复【共享】获取最新的环境变量设置可执行文件下载地址。

Windows下如何体面的修改环境变量



END



如您有任何投稿、问题、建议、需求、合作、后台留言NOVASEC公众号!

Windows下如何体面的修改环境变量

或添加NOVASEC-MOYU 以便于及时回复。

Windows下如何体面的修改环境变量


感谢大哥们的对NOVASEC的支持点赞和关注

加入我们与萌新一起成长吧!


本团队任何技术及文件仅用于学习分享,请勿用于任何违法活动,感谢大家的支持!



本文始发于微信公众号(NOVASEC):Windows下如何体面的修改环境变量

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月29日05:20:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Windows下如何体面的修改环境变量https://cn-sec.com/archives/369126.html

发表评论

匿名网友 填写信息