我创建了一个bat文件来设置我的工作区,方法是将目录更改为工作区目录并调用setupEnv.bat文件。但是当我在PowerShell中执行以下bat文件时, cmd 之后的指令没有执行。 我需要在cmd中调用setupEnv.bat文件。如果我删除 cmd ,它将正常工作。但我想在cmd上调用setupEnv.bat而不是在PowerShell中。
D:
cd D:\WorkSpace\
cmd
call setupEnv.bat
echo "Setup Completed"
答案 0 :(得分:3)
本文介绍了您的具体情况:
Windows IT Pro - Take Charge of Environment Variables in PowerShell
变量消失的原因是.bat
或.cmd
在单独的cmd.exe
进程中运行(当进程终止时,您将丢失变量)。
本文介绍了一个PowerShell函数,可用于运行.bat
或.cmd
脚本并保留它设置的环境变量:
# Invokes a Cmd.exe shell script and updates the environment.
function Invoke-CmdScript {
param(
[String] $scriptName
)
$cmdLine = """$scriptName"" $args & set"
& $Env:SystemRoot\system32\cmd.exe /c $cmdLine |
Select-String '^([^=]*)=(.*)$' |
ForEach-Object {
$varName = $_.Matches[0].Groups[1].Value
$varValue = $_.Matches[0].Groups[2].Value
Set-Item Env:$varName $varValue
}
}
本文还有一些在PowerShell中设置和恢复环境变量值的功能。
答案 1 :(得分:0)
在PowerShell脚本中尝试类似这样的事情:
& start "C:\Temp\test.bat"
答案 2 :(得分:0)
调用setupEnv.bat并调用cmd之后,是否会在PowerShell中保留所有环境变量设置?
没有。从PowerShell调用的任何遗留命令都将在单独的(子)进程中运行。
证明:
wmic process where "name='powershell.exe' or name='cmd.exe'" get CommandLine, name, ParentProcessId, ProcessId /Value
将以上行添加到批处理文件中,例如到setupEnv.bat
并从powershell
D:\bat\setupEnv.bat
,&
call operator & D:\bat\setupEnv.bat
,.
dot sourced & D:\bat\setupEnv.bat
,cmd
的所有上述方法
cmd /D /C D:\bat\setupEnv.bat
或& cmd /D /C D:\bat\setupEnv.bat
或. cmd /D /C D:\bat\setupEnv.bat
。结果始终相同或至少非常相似:
PS D:\PShell> D:\bat\setupEnv.bat
"Setup Completed"
CommandLine="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
Name=powershell.exe
ParentProcessId=4280
ProcessId=6396
CommandLine=C:\Windows\system32\cmd.exe /c ""D:\bat\setupEnv.bat""
Name=cmd.exe
ParentProcessId=6396
ProcessId=4116
从this Foredecker's answer to similar question转发:
虽然子进程可以继承当前的环境变量, 从父母一个工作目录等,没有支持的方式 子进程返回父进程并更改 父母的环境。
解决方案:从cmd
/批处理脚本调用Powershell而不是vice versa