以编程方式刷新PATH中的环境变量引用(Windows 10)

时间:2017-07-19 23:34:54

标签: python windows environment-variables windows-10 environment

背景

我有一个Python脚本,它将环境变量设置到注册表中,然后broadcasts an update using the WinSDK告诉系统一个变量已更新。这与setx和手动环境变量UI类似。这在Windows 7中非常有用。

但是,在Windows 10中,几乎可以正常工作。

这是我的问题

  1. 我设置了一个环境变量(XXX = c:\ my_dir)
  2. 然后我通过注册表将对XXX的引用插入到PATH变量中。我确保使用REG_EXPAND_SZ类型。
  3. 然后我播放了更新。
  4. 当我重新启动新的cmd.exe shell时,我可以看到我的新变量XXX(echo%XXX%),但是,当我查看PATH时,对XXX的引用没有正确扩展。
  5. 为了让我的路径更新能够坚持下去,我需要手动进入环境变量界面,然后编辑"编辑"路径,或者我需要登录并注销。
  6. 奇怪的是,这只会影响PATH。如果我将我的引用添加到另一个变量(例如PYTHONPATH),那么一切似乎都按预期工作。

    我尝试过的事情

    • 杀死explorer.exe任务树并重新启动
    • 对setx进行子处理有效,但我希望将我的实现保留在纯python中。

    更新环境代码

    import ctypes
    
    def update_environment():
        """Uses ctypes to send a message to all windows that the environment has
        been updated. This has the same effect as pressing the 'OK' button in the
        windows environment variables dialog.
    
        References:
            https://support.microsoft.com/en-us/kb/104011"""
        wm_settingchange = 0x001A
        hwnd_broadcast = wintypes.HWND(0xffff)
        smto_abortifhung = 0x0002
        env_message = ctypes.create_unicode_buffer('Environment')
        result = ctypes.windll.user32.SendMessageTimeoutW(hwnd_broadcast,
                                                          wm_settingchange,
                                                          0,
                                                          env_message,
                                                          smto_abortifhung,
                                                          5000,
                                                          0)
        return result
    

    问题

    是否还有其他已知方法强制Windows 10刷新环境(特别是PATH中的环境引用)?

1 个答案:

答案 0 :(得分:0)

我搞砸了一些事情,发现了(我认为)是什么问题。

基本上,我设置的每个注册表项都是REG_EXPAND_SZ类型。在Windows 7中,这似乎工作正常。但是,除非我的XXX键设置为REG_SZ,否则这不会强制在Windows 10中重新扩展我的变量。如果我这样做,那么windows将正确更新变量引用。