【问题标题】:In powershell after changing to cmd unable to call a bat file through a batch script file在powershell中更改为cmd后无法通过批处理脚本文件调用bat文件
【发布时间】:2017-03-11 07:28:57
【问题描述】:

我创建了一个 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中?

【问题讨论】:

    标签: windows powershell batch-file cmd


    【解决方案1】:

    本文针对您的具体情况:

    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 中设置和恢复环境变量值的函数。

    【讨论】:

    • 是的,我知道一种从子cmd 进程获取和处理输出的方法。感谢您提供完整解决方案的链接!但是,我会更改 $cmdLine = """$scriptName"" $args & set & echo CD=%CD%" 并将后续命令添加到 adopt 孩子的当前目录。
    • 而不是$Env:SystemRoot\system32\cmd.exe$Env:ComSpec 怎么样?
    • 是的,除非ComSpec 没有更改为不支持cmd.exe set 命令语法的其他程序(例如PowerShell)。
    【解决方案2】:

    在你的 PowerShell 脚本中尝试这样的事情:

    & start "C:\Temp\test.bat"
    

    【讨论】:

    • 批处理文件中设置的变量会在进程终止时消失。
    【解决方案3】:

    调用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/batch 脚本而不是vice versa调用Powershell

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2014-10-14
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多