Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python脚本能否持久地更改Windows环境变量?(优雅地)_Python_Windows_Scripting_Batch File - Fatal编程技术网

python脚本能否持久地更改Windows环境变量?(优雅地)

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

从我的开始,是否有可能生成一个Python脚本来持续更改Windows环境变量

一旦python解释器终止,对os.environ的更改就不会持久。如果我在UNIX上编写脚本,我可能会执行以下操作:

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)