如何直接从Python脚本修改Windows 10路径变量

问题描述 投票:0回答:1

我希望从 python 脚本中永久地修改窗口内的路径变量。该脚本是一个包装器,可帮助自动安装应用程序,我希望启用 API 将应用程序添加到路径中。

例如,我想安装一个名为

micro
的程序,其安装路径为
C:\Users\USERNAME\Path\to\micro
,然后将该安装路径添加到我的路径变量中,以便我可以在终端中运行
micro

我了解到两种可能的解决方案,但都不起作用:

1.使用 os.environ

在Python中,os模块让你读取环境变量,但实际上不能修改它们。例如:

program_path = "C:\\Users\\USERNAME\\Path\\to\\micro"
new_path = f"{os.environ['PATH']};{program_path}"
os.environ["PATH"] = new_path

这将更新Python脚本中的路径变量,但它实际上并没有在系统上修改它,这正是我想要的。

2.设置x

我知道可以在 Windows 中使用

setx
命令更新路径,但由于某种原因,在 Windows 10 上这会破坏你的路径变量。

这个想法是,您可以从 python 调用

setx
命令并使用它来更新路径变量。您应该能够输入
setx path "%path%;C:\Users\USERNAME\Path\to\micro"
并使其正确更新。

例如,在Python代码中:

program_path = "C:\\Users\\USERNAME\\Path\\to\\micro"
subprocess.Popen(f'setx path "%path%;{program_path}"')

这个应该采用当前路径变量并将程序路径附加到它,但它只是擦除整个路径并将其替换为文字%path%然后是程序路径。

所以现在我的路径是这样的:

%path%
C:\Users\USERNAME\Path\to\micro

任何有关如何使其发挥作用的想法将不胜感激。

python python-3.x windows powershell path
1个回答
3
投票

好吧,经过长时间(且令人厌恶的)研究,我找到了解决方案。这是我为跨平台系统添加到 PATH 变量的方法:

def add_to_path(program_path:str):
    """Takes in a path to a program and adds it to the system path"""
    if os.name == "nt": # Windows systems
        import winreg # Allows access to the windows registry
        import ctypes # Allows interface with low-level C API's

        with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as root: # Get the current user registry
            with winreg.OpenKey(root, "Environment", 0, winreg.KEY_ALL_ACCESS) as key: # Go to the environment key
                existing_path_value = winreg.EnumValue(key, 3)[1] # Grab the current path value
                new_path_value = existing_path_value + program_path + ";" # Takes the current path value and appends the new program path
                winreg.SetValueEx(key, "PATH", 0, winreg.REG_EXPAND_SZ, new_path_value) # Updated the path with the updated path

            # Tell other processes to update their environment
            HWND_BROADCAST = 0xFFFF
            WM_SETTINGCHANGE = 0x1A
            SMTO_ABORTIFHUNG = 0x0002
            result = ctypes.c_long()
            SendMessageTimeoutW = ctypes.windll.user32.SendMessageTimeoutW
            SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, u"Environment", SMTO_ABORTIFHUNG, 5000, ctypes.byref(result),) 
    else: # If system is *nix
        with open(f"{os.getenv('HOME')}/.bashrc", "a") as bash_file:  # Open bashrc file
            bash_file.write(f'\nexport PATH="{program_path}:$PATH"\n')  # Add program path to Path variable
        os.system(f". {os.getenv('HOME')}/.bashrc")  # Update bash source
    print(f"Added {program_path} to path, please restart shell for changes to take effect")

两者都不漂亮,但确实有效。您确实需要重新启动正在运行的 shell 才能生效,但除此之外它是完美的。

编辑:由于这个答案得到了更多的浏览,我将添加一个警告,如果更改未能应用这将擦除你的路径。除了针对每个可能的错误将函数包装在长验证代码中之外,我还没有找到解决方案,并且实际上在 java 工具的供应商代码中发生了这种情况(所以我不是唯一遇到此问题的人) 。与往常一样,注册表有点挑剔,也有点危险,祝你好运

© www.soinside.com 2019 - 2024. All rights reserved.