【问题标题】:Update Environment Variable when changes made from My Computer从我的电脑进行更改时更新环境变量
【发布时间】:2012-06-22 16:03:33
【问题描述】:

我有一个 C++ 程序,它调用 GetEnvironmentVariable() 来获取“路径”变量信息。如果我正在运行我的程序,同时,我通过“MyComputer->Properties->Environment Variables”更改我的“路径”变量?...是否 100% 不可能检索 更新的“路径” ' 来自GetEnvironmentVariable() 的变量,无需重新启动我的程序(和 Visual Studio)。

this postingAnders K 中提到:

“确保在读取环境变量之前重新启动应用程序。如果您打开控制台窗口并更改“我的电脑”上的环境变量,也会发生同样的情况,这些不会在任何现有控制台窗口中注明。您需要重新启动它们以获取新环境变量的副本。”

这是否意味着 100% 无法检索 更新的“路径”变量?我不确定我是否在浪费时间。

另外,我尝试了this 之类的操作,但没有成功。

谢谢。

【问题讨论】:

  • 只是一个想法,而不是一个解决方案......但您可以尝试从您的程序中启动另一个(短期)进程并使用它来读取环境变量
  • 您应该查看 CreateEnvironmentBlock (msdn.microsoft.com/en-us/library/windows/desktop/…)。我以前没有使用过它,所以发布为评论而不是答案,但看起来应该适合你。
  • 或者,要回显@andypaxo,shell 执行“cmd: ECHO %PATH%”,但请确保不要将 cmd 进程创建为现有进程的子进程,否则它只会继承您的环境块.

标签: visual-studio-2008 winapi visual-c++ environment-variables


【解决方案1】:

嗯,不是 100% 不可能。像这样编辑环境变量只会设置注册表项。您可以使用 Regedit.exe 查看它们,导航到 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Control\Session Manager\Environment,您将看到在编辑框中看到的值列表。用户特定的存储在 HKEY_CURRENT_USER\Environment 中。

关键是何时一个进程开始使用这些值。这取决于,一个进程可以从启动它的进程继承环境, CreateProcess() 的 lpEnvironment 参数决定了这一点。传递 NULL 并因此继承是非常常见的,因此启动的进程不会看到更改,它从其父级获得了陈旧环境的副本。真正确定的唯一方法是注销并重新登录,这样您就知道这样一个过程是从改变的环境开始的。或者只是尝试一下,这样你就知道了。

并非 100% 不可能的角度是实际读取这些注册表项。不是很实用,当然也完全不便携。 PATH 环境变量仅在从 shell 启动程序时才有用。

【讨论】:

    【解决方案2】:

    如果您需要它在这个意义上是动态的,那么您使用的是错误的东西。不要使用环境变量,使用注册表项之类的东西。

    【讨论】:

      【解决方案3】:

      环境变量并不直接来自注册表到您的应用程序,它们由资源管理器读取一次,然后由它创建的任何子进程传递/继承。然而,有一种机制允许应用程序在更改注册表值时使用WM_SETTINGCHANGE 广播消息告诉应用程序重新加载这些值,其中lParam 指向包含“环境”的字符串。

      通常,只有资源管理器会处理此消息,但您可以在自己的应用程序中检测到它并直接从注册表中重新读取数据。

      【讨论】:

        【解决方案4】:

        根据乐于助人的响应者的建议,我决定改用注册表项来获取更新的环境变量。

        假设:

            DWORD BufferSize = 16383;  
            TCHAR pathVar[16383];
        

        以前,我做过:

            GetEnvironmentVariable(_T("Path"),pathVar,16383);
        

        如果我通过“我的电脑”->“属性”进行更新,那么它永远不会给我更新的 Path 环境变量。

        现在,我愿意:

            DWORD dwRet = RegGetValue(HKEY_LOCAL_MACHINE, 
            _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"), 
            _T("Path"), RRF_RT_ANY, NULL, (PVOID)&pathVar, &BufferSize);
        
            if(dwRet != ERROR_SUCCESS){
                GetEnvironmentVariable(_T("Path"),pathVar,16383);
            }
        

        从注册表项中获取值。但是,如果由于某种原因RegGetValue() 失败,它将通过GetEnvironmentVariable() 获取值,这可能没有完全更新,但至少我得到了一个我可以使用的值。谢谢大家的建议。

        【讨论】:

          猜你喜欢
          • 2021-08-21
          • 1970-01-01
          • 2016-02-11
          • 2010-10-04
          • 1970-01-01
          • 2014-04-15
          • 2020-12-14
          • 2016-11-10
          • 2018-12-11
          相关资源
          最近更新 更多