简体   繁体   English

如何从C ++更改Windows Shell(cmd.exe)环境变量?

[英]How can I change Windows shell (cmd.exe) environment variables from C++?

I would like to write a program that sets an environment variable in an instance of the shell (cmd.exe) it was called from. 我想编写一个程序,该程序在调用它的shell(cmd.exe)实例中设置环境变量。 The idea is that I could store some state in this variable and then use it again on a subsequent call. 我的想法是,我可以在此变量中存储一些状态,然后在后续调用中再次使用它。

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可以转到目录并返回,但是没有办法将第二次返回原始推送目录。

MSDN states the following : MSDN指出以下内容

Calling SetEnvironmentVariable has no effect on the system environment variables. 调用SetEnvironmentVariable对系统环境变量没有影响。 To programmatically add or modify system environment variables, add them to the HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment registry key, then broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment". 若要以编程方式添加或修改系统环境变量,请将它们添加到HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment注册表项中,然后广播将lParam设置为字符串“ Environment”的WM_SETTINGCHANGE消息。 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. 请注意,此注册表项中列出的环境变量的值限制为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. 我不认为这是可能的。

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 查看完整的信息,对于CreateProccess()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. 话虽如此,使用CMD脚本和PowerShell,父命令外壳程序可以从子进程中获取输出并更新其自身的环境。 This is a common technique. 这是一种常见的技术。

personly, I don't like any kind of complex CMD scripts - they are a bitch to write an debug. 就个人而言,我不喜欢任何复杂的CMD脚本-它们是编写调试工具的bit子。 You may want to do this in PowerShell - there is a learning curve to be sure, but it is much richer. 您可能需要在PowerShell中执行此操作-可以肯定有一个学习曲线,但是它要丰富得多。

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

There is a way... Just inject your code into parent process and call SetEnvironmentVariableA inside cmd's process memory. 有一种方法...只需将代码注入父进程,然后在cmd的进程内存中调用SetEnvironmentVariableA。 After injecting just free the allocated memory. 注入后仅释放分配的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM