windows 从 C++ 更新系统环境变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2273865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:56:38  来源:igfitidea点击:

Update system environment variable from c++

c++windowsenvironment-variables

提问by Russo

I am currently writing an unmanaged C++ program which works with a system environment variable. I am getting the value with GetEnvironmentVariable(...). Now I have an C# program which may change this variable at any time, e.g. like this:

我目前正在编写一个使用系统环境变量的非托管 C++ 程序。我通过 GetEnvironmentVariable(...) 获取值。现在我有一个 C# 程序,它可以随时更改这个变量,例如:

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

The problem is that the C++ program does not update this variable (or its environment block in general) automatically so that I am still working with the old value unless I restart the program which is not really good. Is there a way to update the environment block or preferably another way to read system environment variables?

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

Thanks in advance, Russo

提前致谢,罗素

回答by Jerry Coffin

To make a long story short, environment variables won't work dependably as a form of inter-process communication -- you really need to switch to something else.

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

To work, both programs would need access to some common block of environment variables -- but in reality, each process gets its own, independent copy of a set of environment variables. Worse, most typical (C and C++) standard libraries don't let you even work with thatdirectly -- instead, they make anothercopy of the environment variables for you to work with. When/if you call getenv()or _putenv(), only the program's internal copy of the environment variable block is involved. This means even if you could change a process' environment variables, the program running in that process stillwouldn't get the new data.

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

So, you really need to re-think what you're doing. There are lotsof possibilities for sending data from one program to another, including a Windows message (E.g. WM_COPYDATA), an anonymous or named pipe, a mailslot, a shared memory region, a socket, etc. The list is long, but still doesn't include environment variables.

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

回答by Russo

Thank you guys but I finally figured it out myself. Since the values I receive with GetEnvironmentVariable are not the current ones I read the values directly from the registry. The machine environment variables are stored in

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

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

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

I read them via the RegOpenKeyEx(...) and RegQueryValueEx(...) functions which works perfectly well.

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

回答by Daniel F. Thornton

You are persisting the environment variable changes for as long as is possible, in the context of the call you show. See this MSDN explanationof the EnvironmentVariableTargetenumeration.

在您显示的调用的上下文中,您将尽可能长时间地保留环境变量更改。见这个MSDN解释了的EnvironmentVariableTarget枚举。

With the EnvironmentVariableTarget.Machinesetting you use now, the variable change will persist for as long as your program's process runs, so all other processes will be able to read this variable for the duration of your program's execution:

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

The environment variable is stored or retrieved from the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environmentkey in the Windows operating system registry.

When a user creates the environment variable in a set operation, the operating system stores the environment variable in the system registry, but not in the current process. If any user on the local machine starts a new process, the operating system copies the environment variable from the registry to that process.

When the process terminates, the operating system destroys the environment variable in that process.However, the environment variable in the registry persists until a user removes it programmatically or by means of an operating system tool. [Emphasis mine.]

环境变量是从HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\EnvironmentWindows 操作系统注册表中的键存储或检索的 。

当用户在 set 操作中创建环境变量时,操作系统会将环境变量存储在系统注册表中,而不是在当前进程中。如果本地计算机上的任何用户启动新进程,操作系统会将环境变量从注册表复制到该进程。

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

回答by Daniel F. Thornton

You can't. Each process gets a copy of the environment variables of its parent. As it only gets a copy, it can't change the parent's environment, or that of any other running process.

你不能。每个进程都会获得其父进程的环境变量的副本。由于它只得到一个副本,它不能改变父进程的环境,或任何其他正在运行的进程的环境。

回答by Kevin Shea

Look at putenv() - a C-runtime function (or the MS preferred _putenv() and _putenv_s() - for your C++ equivalent for updating.

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

getenv() and similar reads in an environment string.

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

K

回答by Nikolai Fetissov

I believe it's _putenv()on Windows.

我相信它_putenv()在 Windows 上。