python脚本能否持久地更改Windows环境变量?(优雅地)
从我的开始,是否有可能生成一个Python脚本来持续更改Windows环境变量 一旦python解释器终止,对os.environ的更改就不会持久。如果我在UNIX上编写脚本,我可能会执行以下操作:python脚本能否持久地更改Windows环境变量?(优雅地),python,windows,scripting,batch-file,Python,Windows,Scripting,Batch File,从我的开始,是否有可能生成一个Python脚本来持续更改Windows环境变量 一旦python解释器终止,对os.environ的更改就不会持久。如果我在UNIX上编写脚本,我可能会执行以下操作: set foo=`myscript.py` 但遗憾的是,cmd.exe没有任何类似于sh的back-tick行为的功能。我看到了一个冗长的解决方案。。。这并不完美,因此我们可以在这方面进行改进: for /f "tokens=1* delims=" %%a in ('python ..\mysc
set foo=`myscript.py`
但遗憾的是,cmd.exe没有任何类似于sh的back-tick行为的功能。我看到了一个冗长的解决方案。。。这并不完美,因此我们可以在这方面进行改进:
for /f "tokens=1* delims=" %%a in ('python ..\myscript.py') do set path=%path%;%%a
微软的头脑中肯定有比这更好的解决方案
注意:与之完全相同。您冗长的解决方案可能是最好的主意;我不相信直接从Python实现这一点。本文建议使用临时批处理文件的另一种方法: 您可能想试试,由Mark Hammond开发,包含在中(或可以单独安装)。您可以在中学习如何执行许多与Windows相关的任务
使用PyWin32访问windows COM对象,Python程序可以使用
WScript.Shell
对象的属性-环境变量的集合。windows为每个进程独立地从注册表中存储的值设置环境变量
但是,命名的setx.exe中有一个工具,允许您从命令行更改全局环境变量。使用win32api的我的解决方案:
import os, sys, win32api, win32con
'''Usage: appendenv.py envvar data_to_append'''
def getenv_system(varname, default=None):
'''
Author: Denis Barmenkov <barmenkov at bpc.ru>
Copyright: this code is free, but if you want to use it,
please keep this multiline comment along with function source.
Thank you.
2006-01-28 15:30
'''
v = default
try:
rkey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
try:
v = str(win32api.RegQueryValueEx(rkey, varname)[0])
v = win32api.ExpandEnvironmentStrings(v)
except:
pass
finally:
win32api.RegCloseKey(rkey)
return v
#My set function
def setenv_system(varname, value):
try:
rkey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',0 ,win32con.KEY_WRITE)
try:
win32api.RegSetValueEx(rkey, varname, 0, win32con.REG_SZ, value)
return True
except Exception, (error):
pass
finally:
win32api.RegCloseKey(rkey)
return False
if len(sys.argv) == 3:
value = getenv_system(sys.argv[1])
if value:
setenv_system(sys.argv[1],value + ";" + sys.argv[2])
print "OK! %s = %s" % (sys.argv[1], getenv_system(sys.argv[1]))
else:
print "ERROR: No such environment variable. (%s)" % sys.argv[1]
else:
print "Usage: appendenv.py envvar data_to_append"
导入操作系统、系统、win32api、win32con
''用法:appendenv.py envvar data_to_append''
def getenv_系统(变量名,默认值=无):
'''
作者:丹尼斯·巴门科夫
版权:此代码是免费的,但是如果你想使用它,
请将此多行注释与函数源一起保留。
非常感谢。
2006-01-28 15:30
'''
v=默认值
尝试:
rkey=win32api.RegOpenKey(win32con.HKEY\u LOCAL\u MACHINE,'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
尝试:
v=str(win32api.regqueryvaluex(rkey,varname)[0])
v=win32api.ExpandEnvironmentString(v)
除:
通过
最后:
win32api.RegCloseKey(rkey)
返回v
#我的集合函数
def setenv_系统(变量名,值):
尝试:
rkey=win32api.RegOpenKeyEx(win32con.HKEY\u LOCAL\u MACHINE,'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',0,win32con.KEY\u WRITE)
尝试:
win32api.RegSetValueEx(rkey,varname,0,win32con.REG_SZ,value)
返回真值
例外情况除外,(错误):
通过
最后:
win32api.RegCloseKey(rkey)
返回错误
如果len(sys.argv)==3:
value=getenv_系统(sys.argv[1])
如果值:
setenv_系统(sys.argv[1],value+“;”+sys.argv[2])
打印“确定!%s=%s”%(sys.argv[1],getenv_系统(sys.argv[1]))
其他:
打印“错误:没有这样的环境变量。(%s)”%sys.argv[1]
其他:
打印“用法:appendenv.py envvar数据\u到\u append”
这提供了一个使用内置winreg
库的解决方案
(意大利面)
setx.exe也随Vista一起安装。然而,我得到的印象是,最初的海报实际上是想了解如何修改父进程的环境,而不是使环境变量值在重新启动时保持不变。这不会持续地改变环境。它只是改变了环境变量的一个副本。@Salim Fadhley如果这是你想要的,为什么你要在你的问题中提出不同的要求?通过接受不回答问题的答案,你误导了人们寻找信息……这个问题确实是含糊不清的,但它并不是完全错误的。他提出了一种持续设置变量的方法,而不是全局设置。他的要求是在解释器退出后仍然设置变量,此解决方案就是如此。@DNS对环境变量的持久更改始终意味着相同的事情-更改它,使新值对所有其他进程可见,而不仅仅是选定的进程。我不认为这个问题是完全重复的,因为我的问题只与Windows有关。是否自愿使用“get”是否使用CurrentControlSet以及该集合是否使用ControlSet001?如果是这样,你能解释一下原因吗?@SuperOli,它们几乎在所有情况下都是相等的,但你是对的,在“set”中使用CurrentControlSet会更安全。我不记得当时我为什么那样写。将编辑答案。(更多信息:)
import sys
from subprocess import check_call
if sys.hexversion > 0x03000000:
import winreg
else:
import _winreg as winreg
class Win32Environment:
"""Utility class to get/set windows environment variable"""
def __init__(self, scope):
assert scope in ('user', 'system')
self.scope = scope
if scope == 'user':
self.root = winreg.HKEY_CURRENT_USER
self.subkey = 'Environment'
else:
self.root = winreg.HKEY_LOCAL_MACHINE
self.subkey = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
def getenv(self, name):
key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_READ)
try:
value, _ = winreg.QueryValueEx(key, name)
except WindowsError:
value = ''
return value
def setenv(self, name, value):
# Note: for 'system' scope, you must run this as Administrator
key = winreg.OpenKey(self.root, self.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)
check_call('''\
"%s" -c "import win32api, win32con; assert win32api.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')"''' % sys.executable)