In powershell after changing to cmd unable to call a bat file through a batch script file

耗尽温柔 提交于 2020-01-05 08:51:56

问题


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 as
    • cmd /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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!