【问题标题】:winreg parameters to retrieve PATH in Windows 10在 Windows 10 中检索 PATH 的 winreg 参数
【发布时间】:2020-04-25 05:40:33
【问题描述】:

要在 Windows 10 家庭版计算机上检索 %PATH% 变量的内容,以下 Python 脚本中的 key、subkey 和 name 参数应使用哪些值?

import winreg

def _get_reg_value(key, subkey, name):
    """Return registry value specified by key, subkey, and name.

    Environment variables in values of type REG_EXPAND_SZ are expanded
    if possible.
    """

    key = _winreg.OpenKey(key, subkey)
    try:
        ret = _winreg.QueryValueEx(key, name)
    except WindowsError:
        return None

    else:
        key.Close()
        if ret[1] == _winreg.REG_EXPAND_SZ:
            return expandvars(ret[0])

        else:
            return ret[0] 

请注意,我们在这里没有使用os.environ,因为我们需要与永久路径值进行交互,而不仅仅是与os.environ 公开的运行时值进行交互。

上面的代码示例来自this link。我正在使用它来研究如何使用 Python 以编程方式与 Windows 注册表交互。


尝试失败:

当我在从 Windows CMD 运行的 .py 文件中使用以下语法调用上述函数时,返回的只是 Windows CMD 中的一个空行,后跟一个命令提示符。好像什么都没发生一样。

key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SYSTEM\CurrentControlSet\Control\Session Manager')

_get_reg_value(key, 'Environment', 'Path')  

【问题讨论】:

  • “永久路径值”是什么意思?您从哪里获得“失败尝试”中显示的注册表项路径?在我的机器上,该关键路径不存在。
  • @AdrianMcCarthy 我从regedit 获得了关键路径。更重要的是,我暂时使用 PowerShell 来证明这个概念,并且这个关键路径适用于 PowerShell 版本的代码。所以我认为问题在于 Python 如何与注册表交互。 ...另外,根据永久部分,os.environ 仅在调用 Python 脚本运行时临时更改路径。相比之下,更改注册表项将永远更改全局路径,直到其他东西再次更改注册表项。
  • 就像我说的,我的机器上不存在该密钥(RegEdit 这么说)。依赖未记录的注册表设置会导致可移植性问题。请描述您要解决的问题。另外,您使用的是 32 位还是 64 位版本的 Python?您是否从有权访问该注册表部分的进程运行?
  • @AdrianMcCarthy 要确认您的计算机上不存在密钥,请花 2 分钟以管理员身份打开 PowerShell 并在 PowerShell (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path 中运行以下命令。请注意,要使命令正常工作,您可能还需要先在 PowerShell 中运行 Set-ExecutionPolicy unrestricted。结果应该是PATH的打印输出,在这个OP中我试图通过Python解决。

标签: python python-3.x windows registry winreg


【解决方案1】:

如果 Python 的 winreg 库只是简单地包装了相应的 Windows API,那么您必须使用 open each component of the key。你不能说:

winreg.OpenKey(winreg::HKEY_LOCAL_MACHINE, "FOO\\BAR")

相反,您必须先打开 FOO,然后再打开 BAR:

foo_key = winreg.OpenKey(winreg::HKEY_LOCAL_MACHINE, "FOO")
bar_key = winreg.OpenKey(foo_key, "BAR")

这可能是您问题的根源。

但可能还有更多。在做出这样的改变之后,你应该广播一个WM_SETTINGCHANGE,以便其他进程(比如shell)知道使他们的缓存无效并重新读取系统设置。 PowerShell commandlet 很可能会自动执行此操作。

也可能存在其他问题。例如,如果您在 64 位操作系统上运行 32 位 Python,您可能会遇到注册表重定向,具体取决于您尝试访问的配置单元的哪个部分。

澄清一下,您所说的“永久路径值”是system environment variables 的一部分。如果您有权限(例如,以管理员身份运行),您可以在这些键处修改系统环境块中的路径是正确的。

系统将用户环境变量与系统环境变量合并。如果在两种环境中都定义了 PATH,则最终的 PATH 是系统值和用户值的串联。对于同时具有系统和用户定义的其他变量(例如 TMP),使用用户值。

子进程继承其父进程环境的副本。因此,即使使用 WM_SETTINGCHANGE 广播,它们也可能不会更新其路径以反映您对系统环境块所做的更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 2017-06-07
    • 2022-07-07
    • 2019-07-29
    • 2014-01-08
    • 1970-01-01
    • 2020-04-18
    相关资源
    最近更新 更多