可执行文件如何在父 CMD 或批处理上下文中设置环境变量?
Posted
技术标签:
【中文标题】可执行文件如何在父 CMD 或批处理上下文中设置环境变量?【英文标题】:How can an executable set an environment variable in the parent CMD or batch context? 【发布时间】:2017-09-15 19:14:13 【问题描述】:我有一个设置环境变量的 Windows 控制台可执行文件(称为 SetEnvX.exe)。它在内部调用 Windows API 中的SetEnvironmentVariable
。那个调用成功了。
在执行 SetEnvX.exe 的父 CMD 实例中,如果在 SetEnvX.exe 之后运行SET
,则它创建的环境变量不存在。
如果我用这些行创建一个 TEST.CMD
SetEnvX.exe
set
TEST.CMD 中SET
命令的输出也不显示由 SetEnvX.exe 创建的环境变量。
诸如 SetEnvX.exe 之类的程序如何创建一个环境变量,该变量存在于交互式 CMD shell 或从中执行它的批处理文件的范围内?换句话说,我不想将环境变量放入全局的、持久的环境中。
【问题讨论】:
SetEnvx.exe 是否创建一个新环境然后退出该环境,比如 SETLOCAL ENDLOCAL? 【参考方案1】:这是不可能的。每当您调用SetEnvX.exe
cmd.exe 时,都会生成一个从 cmd.exe 继承环境变量的子进程。
SetEnvX.exe
在其环境中设置环境变量,但当它完成时,它的环境块消失。所以父 cmd.exe 不会从子 SetEnvX.exe
获取任何变量。
TL;DR:
子进程可以继承父进程的环境变量,但父进程退出时不能继承子进程的环境变量。
解决方法:
如果你自己编译SetEnvX.exe
,不用设置环境变量,你可以打印值,然后在cmd.exe中捕获。例如:
for /f "delims=" %%k in ('SetEnvX.exe') do set VARIABLE=%%k
【讨论】:
从技术上讲,(有时)可以打开父进程并重写其环境块,但这是不可取的,也是糟糕的设计。您需要一种协作设计,例如将新变量写入标准输出的解决方法。 请注意,环境变量是 Unicode,for /f
使用控制台的当前输出代码页从管道中逐行解码。一般来说,您可能需要通过将控制台设置为代码页 65001 (UTF-8) 并让 SetEnvX.exe 将 UTF-8 写入标准输出来进行更多合作。
cmd /k "set a=b"
在你的 cmd 文件中将在返回时将a
设置为当前命令行。【参考方案2】:
每个进程在出生时都会继承其父进程的变量。您不能从孩子那里继承变量。虽然注册表中有一个“全局持久环境”,但不是随机 CMD.EXE 进程中的环境。
注意批处理文件是由CMD.EXE执行的,一般没有自己的进程。
【讨论】:
以上是关于可执行文件如何在父 CMD 或批处理上下文中设置环境变量?的主要内容,如果未能解决你的问题,请参考以下文章
Java环境变量设置成功后运行cmd时提示错误 不是内部或外部命令,也不是可运行的程序或批处理文件
windows7 64bit下mvn命令后提示‘cmd’不是内部或外部命令,也不是可执行程序或批处理文件
运行cmd后,arp-a显示:不是内部或外部命令,也不是可运行的程序或批处理程序。怎么办?
cmd窗口输入code打不开vscode。提示不是内部或外部命令,也不是可运行的程序或批处理文件?