【问题标题】:Setting environment variables with batch file lauched by Powershell script使用 Powershell 脚本启动的批处理文件设置环境变量
【发布时间】:2018-08-08 05:34:08
【问题描述】:

我有一个名为 SET_ENV.bat 的批处理脚本,其中包含其他批处理脚本使用的环境变量。目前这个 SET_ENV.bat 由现有的批处理脚本启动。

现在我需要使用 Powershell 脚本,我想启动相同的 SET_ENV.bat。我设法做到了这一点:

cmd.exe /c ..\..\SET_ENV.bat

我知道批处理文件已运行,因为它包含回显

echo *** Set the environment variables for the processes ***

但是查看环境变量后,我可以看到它们都没有更新。是否有什么阻止我使用 Powershell + 批处理文件组合更新环境变量?

我已经直接从命令行尝试了 SET_ENV.bat 并且它可以工作。我也尝试过使用“-Verb runAs”的 Start-Process cmdlet,但这没有任何好处。

【问题讨论】:

  • 我发现有人在这里谈论类似的事情:stackoverflow.com/questions/20077820/… 但这并没有提供为什么它不起作用的答案/原因。
  • 您可以直接使用 PowerShell 来执行此操作。像这样的东西可以工作[Environment]::SetEnvironmentVariable("TestVariableName", "My Value", "<Option>")
  • @VivekKumarSingh:或者只是$Env:TestVariableName = 'MyValue'。无需将事情过度复杂化。
  • @Joey:是的,也可以这样做。我曾见过需要设置范围的情况。因此,过于复杂的代码。 :)

标签: powershell batch-file environment-variables


【解决方案1】:

在批处理命令结束时再次启动 PowerShell 将保留到目前为止的 every 环境变量。

我的用例是:设置 Anaconda 环境,设置 MSVC 环境,然后继续。问题是 Anaconda 和 MSCV 都有一个单独的批处理脚本来初始化环境。

以下从 PowerShell 开始的命令将:

  • 初始化 Anaconda
  • 初始化 MSVC
  • 重新启动 PowerShell
cmd.exe "/K" '%USERPROFILE%\apps\anaconda3\Scripts\activate.bat %USERPROFILE%\apps\anaconda3 && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" && powershell'

只需将路径交换为您需要的路径。请注意,如果路径包含空格,则需要在双引号 " 内。

分解上面的调用:

  • cmd.exe "/K":调用cmd,命令执行完毕后不退出/K

剩下的是完整的命令,用单引号括起来'

  • %USERPROFILE%\apps\anaconda3\Scripts\activate.bat %USERPROFILE%\apps\anaconda3:使用参数...\anaconda3 调用activate.bat
  • && "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat": && 如果前面的命令没有失败,请运行 MSVC vars 设置文件。它包含在 " 中,因为其中包含空格。
  • && powershell:终于运行 PowerShell。现在将包含上述环境变量中的所有环境变量。

只是添加了一种更好的方法来进行上述设置:使用 Anaconda 的 PowerShell 初始化脚本来实际让它在提示符上显示环境名称。我不会分解它,因为它只是上面的修改命令。

cmd.exe "/K" '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" && powershell -noexit -command "& ''~\apps\anaconda3\shell\condabin\conda-hook.ps1'' ; conda activate ''~\apps\anaconda3'' "'

注意powershell 调用中的单引号全部加倍以转义它们

【讨论】:

    【解决方案2】:

    环境变量对于进程来说是本地的,并且会被继承(至少在默认情况下)新的子进程。在您的情况下,您启动了一个 cmd 的新实例,它继承了 PowerShell 的环境变量,但有自己的环境。然后,批处理文件会更改该 cmd 实例的环境,该实例随后会关闭,然后您将返回到您的 PowerShell 脚本。自然,PowerShell 的环境没有任何变化。

    它在cmd 中工作,因为批处理文件是在同一个进程中执行的,所以批处理文件可以设置环境变量,然后它们可用,因为批处理文件不是在一个新工艺。如果您在交互式cmd 会话中使用cmd /c setenv.cmd,您会发现您的环境也没有改变。

    您可以尝试其他选项,例如在与语言无关的文件中指定环境变量,以便由cmd 或 PowerShell 读取以相应地设置环境。或者,您可以在首次运行批处理文件后从 cmd 启动 PowerShell 脚本。或者您可以在您的用户帐户下设置这些环境变量,以不再需要关心它们。或者您只有一个setenv.cmd 和一个setenv.ps1,并保持它们同步更新。

    【讨论】:

    • 感谢您的评论!我认为环境变量对任何进程都是可见的,因为我已经可以看到我上周设置的一些变量。
    • 您已经为系统范围和您的用户帐户配置了一组“基本”环境变量。这些存储在注册表中,并且只要这些更改(至少通过设置 UI),资源管理器就会更新自己的环境。然后这会导致新进程(几乎总是由 Explorer 启动)获取它们,因为它们获得了 Explorer 环境的副本。
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 2014-03-03
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多