zoukankan      html  css  js  c++  java
  • windows环境用python修改环境变量的注意点(含代码)

    1、部分环境变量字段需要保留原来的值,只是做添加,不可以替换

    2、Path和PATH对于python来说是一样的,也就是说存在名为Path的环境变量时,添加PATH的环境变量,会覆盖原有的Path环境变量,需要做判断

    3、java_home之类的home路径,若原先已存在路径,哪怕已添加路径,系统也只会从第一个路径查找,而不是新添加的路径查找

    4、java安装后配置环境变量时,要注意环境变量是配置在哪个用户下面,所有用户公用的是SYSTEM用户的环境变量

    5、设定安装路径时,使用C:而不是C:\,否则安装后由于tomcat或java的path为C:\java之类的,导致系统报错

    The JAVA_HOME environment variable is not defined correctly
    This environment variable is needed to run this program
    NB: JAVA_HOME should point to a JDK not a JRE
    这个报错也可能是windows的本地环境与远程执行环境不同导致的,为了方便,全部用python调用底层api去运行程序或进程或服务,在运行的bat开头set环境变量,然后解决了

    代码如下:

    # coding=utf8
    import os
    import sys
    from subprocess import check_call
    
    if sys.hexversion > 0x03000000:
        import winreg
    else:
        import _winreg as winreg
    import subprocess
    
    
    def run_cmd(cmd, cwd=None, runas=None):
        u"""
        运行cmd命令。
        """
        if not sys.platform.startswith('win') and runas and runas != 'root':
            cmd = 'su - {} -c "{}"'.format(runas, cmd)
        # logger.info(cmd)
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT,
                                shell=True,
                                cwd=cwd)
        return proc
    
    
    def get_output(cmd, cwd=None, wait=True, runas=None):
        u"""
        获得命令执行后的标准输出或错误输出。
        """
        proc = run_cmd(cmd, cwd=cwd, runas=runas)
        lines = []
        if wait:
            while proc.poll() is None:
                if proc.stdout:
                    lines.extend(proc.stdout.readlines())
        lines.extend(proc.stdout.readlines())
        return lines
    
    
    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'SYSTEMCurrentControlSetControlSession ManagerEnvironment'
    
        def search(self, name):
            key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_READ)
            key_value = ''
            try:
                i = 0
                while i >= 0:
                    key_value, path, value = winreg.EnumValue(key, i)
                    i += 1
                    if key_value == name:
                        break
            except:
                key_value = ''
            return key_value
    
        def getenv(self, name):
            key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_READ)
            try:
                value, _ = winreg.QueryValueEx(key, name)
            except:
                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)
    
        def get_userenv(self, name):
            # Note: for 'system' scope, you must run this as Administrator
            key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_ALL_ACCESS)
            value, _ = winreg.QueryValueEx(key, name)
            return value
    
    
    def set_env_path(env_obj, env_name, env_path,refresh=False):
        need_add = False
        path_values = None
        exist_path = None
        if env_obj.search(env_name):
            exist_path = env_obj.get_userenv(env_name)
        if not exist_path and env_obj.search(env_name.upper()):
            exist_path = env_obj.get_userenv(env_name.upper())
    
        if refresh:
            exist_path=None
        if exist_path:
            path_values = [i for i in exist_path.split(';')]
            for i in env_path.split(';'):
                if i not in path_values:
                    path_values.append(i)
                    need_add = True
        if not need_add and path_values:
            return '已添加环境变量{}:{}'.format(env_name, exist_path)
    
        if path_values:
            env_path = ';'.join(path_values)
    
        env_obj.setenv(env_name, os.path.expanduser(env_path))
        path_value = env_obj.get_userenv(env_name)
        return '已添加环境变量{}:{}'.format(env_name, path_value)
    
    
    if __name__ == '__main__':
        env_obj = Win32Environment(scope="SYSTEM")
        print set_env_path(env_obj, 'JAVA_HOME', java_home,refresh=True)
    
        print set_env_path(env_obj, 'Path', '%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin')
    
        print set_env_path(env_obj, 'CLASSPATH',
                           '.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar')
    

      

  • 相关阅读:
    Github挂载大文件解决方案
    UWP 更强大的文件获取能力
    UWP 打开系统设置面板
    Windows 10
    Flutter
    Android笔记(三):View一些值得注意的地方
    Android笔记(二):savedIndstanceState 和 Bundle
    Android笔记(一):this 的表示范围和 Context
    用atom写LaTeX文档
    博客园LaTeX数学公式功能及效果展示
  • 原文地址:https://www.cnblogs.com/slqt/p/7145500.html
Copyright © 2011-2022 走看看