如何从 C++ 更改 Windows shell (cmd.exe) 环境变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/774047/
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
How can I change Windows shell (cmd.exe) environment variables from C++?
提问by Steve Rowe
I would like to write a program that sets an environment variable in an instance of the shell (cmd.exe) it was called from. The idea is that I could store some state in this variable and then use it again on a subsequent call.
我想编写一个程序,在调用它的 shell (cmd.exe) 实例中设置环境变量。这个想法是我可以在这个变量中存储一些状态,然后在后续调用中再次使用它。
I know there are commands like SetEnvironmentVariable, but my understanding is that those only change the variable for the current process and won't modify the calling shell's variables.
我知道有像 SetEnvironmentVariable 这样的命令,但我的理解是这些命令只会更改当前进程的变量,而不会修改调用 shell 的变量。
Specifically what I would like to be able to do is create a command that can bounce between two directories. Pushd/Popd can go to a directory and back, but don't have a way of returning a 2nd time to the originally pushed directory.
具体来说,我希望能够做的是创建一个可以在两个目录之间弹跳的命令。Pushd/Popd 可以转到一个目录并返回,但无法第二次返回到最初推送的目录。
回答by Jeff Yates
Calling
SetEnvironmentVariable
has no effect on the system environment variables. To programmatically add or modify system environment variables, add them to theHKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
registry key, then broadcast aWM_SETTINGCHANGE
message withlParam
set to the string "Environment". This allows applications, such as the shell, to pick up your updates. Note that the values of the environment variables listed in this key are limited to 1024 characters.
调用
SetEnvironmentVariable
对系统环境变量没有影响。以编程方式添加或修改系统环境变量,把它们添加到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
注册表项,然后广播WM_SETTINGCHANGE
与信息lParam
设置为字符串“环境”。这允许应用程序(例如外壳程序)获取您的更新。请注意,此项中列出的环境变量的值限制为 1024 个字符。
Considering that there are two levels of environment - System and Process - changing those in the shell would constitute changing the environment of another process. I don't believe that this is possible.
考虑到有两个级别的环境 - 系统和进程 - 更改 shell 中的那些将构成更改另一个进程的环境。我不相信这是可能的。
回答by Sanjaya R
A common techniques is the write an env file, that is then "call"ed from the script.
一种常见的技术是编写一个 env 文件,然后从脚本“调用”该文件。
del env.var
foo.exe ## writes to env.var
call env.var
回答by Foredecker
In Windows when one process creates another, it can simply let the child inherit the current environment strings, or it can give the new child process a modified, or even completely new environment.
在 Windows 中,当一个进程创建另一个进程时,它可以简单地让子进程继承当前的环境字符串,或者它可以给新的子进程一个修改过的,甚至是全新的环境。
See the full info for the CreateProccess() win32 API
查看CreateProcess() win32 API的完整信息
There is no supported way for a child process to reach back to the parent process and change the parent's environment.
没有支持子进程返回到父进程并更改父进程的环境的方式。
That being said, with CMD scripts and PowerShell, the parent command shell can take output from the child process and update its own environment. This is a common technique.
也就是说,使用 CMD 脚本和 PowerShell,父命令 shell 可以从子进程获取输出并更新自己的环境。这是一种常见的技术。
personly, I don't like any kind of complex CMD scripts - they are a bitch to write an debug. You may want to do this in PowerShell - there is a learning curve to be sure, but it is much richer.
就个人而言,我不喜欢任何类型的复杂 CMD 脚本——它们是编写调试程序的婊子。您可能想在 PowerShell 中执行此操作 - 有一个学习曲线可以肯定,但它更丰富。
回答by jazu100
There is a way... Just inject your code into parent process and call SetEnvironmentVariableA inside cmd's process memory. After injecting just free the allocated memory.
有一种方法......只需将您的代码注入父进程并在cmd的进程内存中调用SetEnvironmentVariableA。注入后释放分配的内存。