【问题标题】:Update system environment variable from c++从 C++ 更新系统环境变量
【发布时间】:2011-01-17 10:45:19
【问题描述】:

我目前正在编写一个与系统环境变量一起工作的非托管 C++ 程序。我通过 GetEnvironmentVariable(...) 获得了价值。 现在我有一个可以随时更改此变量的 C# 程序,例如像这样:

Environment.SetEnvironmentVariable("CalledPath", System.Windows.Forms.Application.ExecutablePath, EnvironmentVariableTarget.Machine);

问题是 C++ 程序不会自动更新这个变量(或者它的环境块),所以我仍然使用旧值,除非我重新启动程序,这不是很好。 有没有办法更新环境块或者最好是另一种读取系统环境变量的方法?

提前致谢, 罗素

【问题讨论】:

  • 我认为无法更新正在运行的程序的环境。

标签: c++ windows environment-variables


【解决方案1】:

长话短说,环境变量不能作为一种进程间通信的形式可靠地工作——你真的需要切换到其他东西。

为了工作,两个程序都需要访问一些通用的环境变量块——但实际上,每个进程都有自己的一组环境变量的独立副本。更糟糕的是,大多数典型(C 和 C++)标准库甚至不允许您直接使用 that —— 相反,它们为您制作环境变量的 another 副本一起工作。当/如果您调用getenv()_putenv() 时,仅涉及环境变量块的程序内部副本。这意味着即使您可以更改进程的环境变量,在该进程中运行的程序仍然不会获得新数据。

所以,你真的需要重新考虑你在做什么。从一个程序向另一个程序发送数据的可能性有很多,包括 Windows 消息(例如 WM_COPYDATA)、匿名或命名管道、邮槽、共享内存区域、套接字等。列表很长,但仍然不包含环境变量。

【讨论】:

    【解决方案2】:

    谢谢你们,但我终于自己弄清楚了。 由于我使用 GetEnvironmentVariable 收到的值不是当前值,因此我直接从注册表中读取这些值。 机器环境变量存放在

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

    我通过运行良好的 RegOpenKeyEx(...) 和 RegQueryValueEx(...) 函数读取它们。

    【讨论】:

      【解决方案3】:

      你不能。每个进程都获得其父进程的环境变量的副本。因为它只获取一个副本,所以它不能改变父进程的环境,或者任何其他正在运行的进程的环境。

      【讨论】:

        【解决方案4】:

        在您显示的调用上下文中,您将尽可能长时间地保留环境变量更改。请参阅 EnvironmentVariableTarget 枚举中的 this MSDN explanation

        使用您现在使用的EnvironmentVariableTarget.Machine 设置,只要您的程序进程运行,变量更改就会持续存在,因此所有其他进程将能够在您的程序执行期间读取此变量:

        环境变量被存储或 从 Windows 中的HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment 键 操作系统注册表。

        当用户创建环境时 集合操作中的变量, 操作系统存储 系统环境变量 注册表,但不在当前 过程。 如果本地有任何用户 机器开始一个新的过程, 操作系统复制 注册表中的环境变量 到那个过程。

        当进程终止时, 操作系统破坏 该过程中的环境变量。 但是,环境变量在 注册表一直存在,直到用户 以编程方式或通过 操作系统工具的手段。 [强调我的。]

        【讨论】:

          【解决方案5】:

          查看 putenv() - C 运行时函数(或 MS 首选的 _putenv() 和 _putenv_s() - 用于更新的 C++ 等效项。

          getenv() 和类似的读取环境字符串。

          K

          【讨论】:

          • 我认为这不会影响另一个正在运行的进程的环境
          【解决方案6】:

          我相信它是 Windows 上的 _putenv()

          【讨论】:

          • 我认为这不会影响另一个正在运行的进程的环境
          • 当然不是——你必须派生一个进程来继承环境。
          • OP 正在尝试传递变量而不重述它正在传递给的程序