起因
因为需要安装不同版本的JDK,并且需要通过环境变量不断的切换版本。网上找遍了没有找到想要的,而且chatGPT对这方面罕见的需求处理也是一般,漏洞百出。
解决思路
刚开始想通过bat执行命令,但找不到想要的命令,set,wmic,path,都想过,但要么是不能是追加(也就因为这个,我把系统环境变量误删),要么是不好处理用户变量和系统变量(虽然可以一堆全部塞进系统变量里),最后我发现可以直接修改注册表来改环境变量,于是选择了Python的winreg库来修改注册表,并通过bat脚本运行程序,传入参数。
代码如下
提醒:在测试脚本功能前请做好环境变量的备份,以防脚本有未发现的错误,导致环境变量丢失,别问我为什么要强调
提醒:在测试脚本功能前请做好环境变量的备份,以防脚本有未发现的错误,导致环境变量丢失,别问我为什么要强调
提醒:在测试脚本功能前请做好环境变量的备份,以防脚本有未发现的错误,导致环境变量丢失,别问我为什么要强调
这个代码可以指定的键加入指定的值,并且可以选择系统或用户,还有追加替换删除三个模式
from winreg import OpenKey, SetValueEx, CloseKey, EnumValue, DeleteValue, HKEY_CURRENT_USER, REG_EXPAND_SZ, HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS
from argparse import ArgumentParser
def Whether(key, name, value):
all_key = []
i = 0
while True:
try:
subkey = EnumValue(key, i)
i += 1
all_key.append(subkey)
except Exception as result:
# print(result)
break
for nv in all_key:
if name == nv[0]:
if value in nv[1]:
return '2'
else:
if nv[1][-1:] != ';':
return nv[1]+';'
return nv[1]
return '0'
def GetKey(user):
if user == 'user' or user == 'User' or user == 'USER':
# 打开注册表的"HKEY_CURRENT_USER\Environment"键
key = OpenKey(HKEY_CURRENT_USER, r'Environment', 0, KEY_ALL_ACCESS)
print('正改变用户环境变量')
else:
# 打开注册表的"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"键
key = OpenKey(HKEY_LOCAL_MACHINE, r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 0, KEY_ALL_ACCESS)
print('正改变系统环境变量')
return key
def deleteV(name, user):
key = GetKey(user)
# 删除
DeleteValue(key, name)
print('删除' + name)
# 关闭注册表键
CloseKey(key)
def replaceV(name, value, user):
key = GetKey(user)
# 覆盖写入
SetValueEx(key, name, 0, REG_EXPAND_SZ, value)
print("已覆盖"+name+"为"+value)
# 关闭注册表键
CloseKey(key)
def addV(name, value, user):
key = GetKey(user)
#判断子项是否存在
W = Whether(key, name, value)
if W == '0':
print('创建' + name + '并添加' + value)
elif W == '2':
print(value + '已存在于' + name)
# 关闭注册表键
CloseKey(key)
return 0
else:
# 获取原本的子项的值
print(value + "已添加于" + name)
value = W + value
# 覆盖写入
SetValueEx(key, name, 0, REG_EXPAND_SZ, value)
# 关闭注册表键
CloseKey(key)
def main():
parser = ArgumentParser(description='Input parameters')
parser.add_argument('--m', type=str,help='mods:a(add)/r(replace)/d(delete)', required=True)
parser.add_argument('--n', type=str,help='name', required=True)
parser.add_argument('--v', type=str,help='value', required=True)
parser.add_argument('--u', type=str,help='sysytem/user', required=True)
args = parser.parse_args()
if args.u != 'system' and args.u != 'user':
raise ValueError("User's value is error.")
if args.m == 'a':
addV(args.n, args.v, args.u)
elif args.m == 'r':
replaceV(args.n, args.v, args.u)
elif args.m == 'd':
deleteV(args.n, args.u)
else:
raise ValueError("Mod's value is error.")
if __name__ == "__main__":
try:
print('````````````````````````')
main()
print('````````````````````````')
except Exception as result:
print(result)
打包好的程序
链接:https://pan.baidu.com/s/1EwokrsskG3qHkZeMLcWXKA?pwd=iq0u
请配合bat命令使用
bat使用
setlocal
set "script_dir=%~dp0"
set "app_path=%script_dir%\ChangeEnvVar.exe"
::如果要添加多个可以--v拼接多个地址,或者多次执行语句,并且注意模式a为追加,r为替换,d为删除,如果没有都会创建
start "" "%app_path%" --u=system --n=test-name --v=test-value1 --m=a
::防止两个程序同时运行暂停一秒
timeout /t 1 /nobreak >nul
start "" "%app_path%" --u=system --n=test-name --v=test-value2 --m=a
endlocal
如果要加入多个地址就在bat代码中,多次执行程序就可以了
最后
不知大家有没有更方便的方法,比如纯bat脚本。