Powershell脚本启动批处理文件设置环境变量

toiithl6  于 2023-02-04  发布在  Shell
关注(0)|答案(3)|浏览(159)

我有一个名为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”启动进程cmdlet,但没有任何效果。

atmip9wb

atmip9wb1#

在批处理命令结束时再次启动PowerShell将保留到目前为止的 every 环境变量。
我的使用案例是:设置Anaconda环境,设置MSVC环境,继续。问题是Anaconda和MSCV都有一个单独的批处理脚本来初始化env。
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安装文件。由于"中有空格,因此将其 Package 在其中。
  • && powershell:最后运行PowerShell。这将包含上面的所有环境变量。

只是添加一个更好的方法来完成上述设置:使用Anaconda的PowerShell init脚本,使其在提示符处显示环境名称。我不会详细说明这一点,因为它只是上面的一个修改命令。

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调用中的单引号都是双引号,以进行转义

jogvjijk

jogvjijk2#

环境变量是进程的局部变量,可以被继承(至少在默认情况下)添加到新的子进程。在您的情况下,您启动了cmd的新示例,它继承了PowerShell的环境变量,但有自己的环境。批处理文件随后更改了该cmd示例的环境,该示例随后关闭,您返回到PowerShell脚本。自然,PowerShell的环境没有任何变化。
它可以在cmd中工作,因为批处理文件在同一进程中执行,所以批处理文件 * 可以 * 设置环境变量,并且它们随后可用,因为批处理文件没有在新进程中执行。如果您在交互式cmd会话中使用cmd /c setenv.cmd,您会发现您的环境也没有改变。
您可以尝试另一个选项,例如在语言不可知的文件中指定环境变量,可由cmd或PowerShell读取,以相应地设置环境。或者,您可以在首次运行批处理文件后从cmd启动PowerShell脚本。或者,您可以在您的用户帐户下设置这些环境变量,使其不再需要处理。或者您只需要一个setenv.cmd和一个setenv.ps1,并保持它们同步更新。

b09cbbtk

b09cbbtk3#

总结

将环境变量写入文件,然后加载它们。

示例

我在下面包含了一个MWE,它通过保存和加载VS-studio环境来举例说明这一点。

用法

要运行该脚本,请调用New-Environment。现在您将进入VS2022环境。

工作原理

第一次调用New-Environment时,VS-studio环境批处理文件将运行,但结果将保存到磁盘。返回PowerShell时,结果将从磁盘加载。以后的调用只使用保存的结果,而无需再次运行环境激活器如果你想重新保存VS-studio环境,比如有什么改变,可以使用New-Environment -refresh参数。

脚本
  • 注意:此脚本必须存在于powershell $profile中,以便第二个示例可以访问此函数!请确保更改VS路径以反映您自己的安装。*
function New-Environment()
{
    param (
        [switch]
        $refresh
    )
    Write-Host "Env vars now: $($(Get-ChildItem env: | measure-object).Count)"
    $fileName = "$home\my_vsenviron.json"

    if ((-not $refresh) -and (Test-Path $fileName -PathType Leaf))
    {
        Import-Environment($fileName)
        return;
    }

    $script = '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" && '
    $script += "pwsh --command Export-Environment `"$fileName`""

    &"cmd.exe" "/C" $script

    Import-Environment($fileName)
}

function Export-Environment($fileName)
{
    Get-ChildItem env: | Select-Object name,value | ConvertTo-Json | Out-File $fileName
    Write-Host "I have exported the environment to $fileName"
}

function Import-Environment($fileName)
{
    Get-Content $fileName | ConvertFrom-json | ForEach-Object -process {Set-Item "env:$($_.Name)" "$($_.Value)"}
    Write-Host "I have imported the environment from $fileName"
    Write-Host "Env vars now: $($(Get-ChildItem env: | measure-object).Count)"
}

相关问题