问题
I created a bat file to setup my workspace by changing the directory to the workspace directory and calling the setupEnv.bat file. But while I'm executing the below bat file in PowerShell, the instructions after cmd are not executing. I need to call the setupEnv.bat file in cmd. If I remove the cmd it will work fine. But I want call the setupEnv.bat on cmd not in PowerShell.
D:
cd D:\WorkSpace\
cmd
call setupEnv.bat
echo "Setup Completed"
- After calling the setupEnv.bat and calling cmd, will it keep all the environment variable setup in the PowerShell ?
回答1:
This article addresses your exact scenario:
Windows IT Pro - Take Charge of Environment Variables in PowerShell
The reason the variables disappear is that a .bat
or .cmd
runs in a separate cmd.exe
process (when the process terminates, you lose the variables).
The article presents a PowerShell function you can use to run a .bat
or .cmd
script and retain the environment variables it sets:
# 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
}
}
The article also has a couple of functions for setting and restoring environment variable values in PowerShell.
回答2:
try Something like this into your PowerShell script:
& start "C:\Temp\test.bat"
回答3:
After calling the setupEnv.bat and calling cmd, will it keep all the environment variable setup in the PowerShell?
No. Any legacy commands invoked from PowerShell will run in a separate (child) process.
Proof:
wmic process where "name='powershell.exe' or name='cmd.exe'" get CommandLine, name, ParentProcessId, ProcessId /Value
Add above line to your batch-file, e.g. to setupEnv.bat
and call it from powershell
- either directly, e.g.
D:\bat\setupEnv.bat
, - or using & call operator
& D:\bat\setupEnv.bat
, - or . dot sourced
& D:\bat\setupEnv.bat
, - or modify all above methods calling
cmd
ascmd /D /C D:\bat\setupEnv.bat
, or& cmd /D /C D:\bat\setupEnv.bat
, or. cmd /D /C D:\bat\setupEnv.bat
.
Result is always the same or at least very alike:
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
Paraphrased from this Foredecker's answer to similar question:
While a child process can inherit the current environment variables, working directory etc. from parent one, there is no supported way for a child process to reach back to the parent process and change the parent's environment.
Solution: call Powershell from cmd
/batch script rather than vice versa
来源:https://stackoverflow.com/questions/42711294/in-powershell-after-changing-to-cmd-unable-to-call-a-bat-file-through-a-batch-sc