在更改为cmd后的powershell中,无法通过批处理脚本文件调用bat文件

时间:2017-03-10 05:58:49

标签: windows powershell batch-file cmd

我创建了一个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"
  • 调用setupEnv.bat并调用cmd后,它是否会在PowerShell中保留所有环境变量设置?

3 个答案:

答案 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