在Windows PowerShell中运行VS 2017生成工具

4
我不喜欢IDE,所以我安装了VS 2017 Build Tools,这样我就可以通过命令行工作。
安装进行得很顺利,在Windows CMD中一切正常,然而PowerShell更好用,我更喜欢使用PS。问题在于根据MSDN的说法:
“Visual C++命令行工具使用PATH、TMP、INCLUDE、LIB和LIBPATH环境变量,还可能使用特定于工具的环境变量。由于这些环境变量的值是针对您的安装特定的,并且可以通过产品更新或升级进行更改,因此我们建议您使用vcvarsall.bat或Developer Command Prompt快捷方式,而不是自己设置它们。有关编译器和链接器使用的特定环境变量的信息,请参阅CL环境变量和LINK环境变量。”
我不应该自己设置环境变量,这对我来说没问题,唯一的问题是当我在PS中运行vcvarsall.bat时,没有环境变量发生改变。我对PS不熟悉,所以我猜测.bat文件不能改变会话环境变量。如果是这样的话,那么我就无法使用PS。另外,CLLINK变量从未出现过,我将在下面解释。
我想找出这些变量是什么。我在运行batch文件之前和之后将所有变量输出到文本文件中,并编写了一个简短的Java程序来查找任何新的或修改过的内容。这些是它们。如您所见,CLLINK变量不存在。
我该如何解决这个问题?我考虑编写自己的batch文件,但如果第一个文件不起作用,我的文件为什么会起作用呢?我在附加的MSDN页面上没有看到任何关于如何使此功能在PowerShell中工作的链接。

你链接的 MSDN 页面中提到的 CL 环境变量LINK 环境变量链接。你有没有点击它们看看它们添加了什么? - Ken White
2
编写一个批处理文件,其中1)调用vcvarsall.bat,并2)调用PowerShell。然后,PowerShell将使用为其准备的环境块运行。反过来不起作用,因为PowerShell本身不执行批处理文件--它依赖于cmd来执行,作为子进程,它具有自己的环境块,不反映在其父进程上。 - Jeroen Mostert
@JeroenMostert 我写了批处理文件:https://hastebin.com/omeparoruc.bat 但它似乎不起作用。如果我双击它,CMD会弹出一秒钟,显示环境已初始化,然后消失,什么也没有发生。此外,如果我在CMD会话中运行批处理文件,它与双击它的效果相同,甚至不会在CMD中打开PS。 - Ungeheuer
@JeroenMostert 谢谢。它有效。如果您将其作为答案,我会选择并点赞它。我还尝试了这行代码 start powershell 来尝试一下。如果我只是这样做,PS 就会在其默认窗口中打开,带有默认的背景等等。如果我执行 start "" powershell,它会在 CMD 窗口中打开 PS。有什么想法吗?再次感谢您的帮助,我担心我必须编写一些复杂的 PS 脚本。 - Ungeheuer
不,我不知道START在所有方面的工作方式,这可能是另一个问题的主题。但是,您可以使用像procexp这样的工具轻松验证start "" powershell仍然只启动PowerShell,而不是cmd。它的窗口只是看起来不同。没有所谓的"cmd窗口",而是cmd和PowerShell都使用控制台窗口(由conhost.exe托管)。如果你真的想改变PowerShell的标题栏而不仅仅是学术好奇心,我会从PowerShell本身使用$host.UI.RawUI.WindowTitle - Jeroen Mostert
显示剩余3条评论
2个回答

4

编写一个批处理文件,它会执行以下两个步骤:1)调用vcvarsall.bat,2)调用PowerShell。示例如下(此示例适用于VS 2015):

@CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %*
@start powershell
< p>%*允许我们将与vcvarsall.bat相同的参数传递给此文件。

然后,PowerShell将运行并准备好环境块。反过来则不起作用,因为PowerShell不会自行执行批处理文件——它依赖于cmd完成此任务,而作为子进程,它具有自己的环境块,无法反映其父进程的环境。


1
对于VS2017构建工具,调用路径为C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat - John Oxley

3
<#
.SYNOPSIS
    Invokes the specified batch file and retains any environment variable changes it makes.
.DESCRIPTION
    Invoke the specified batch file (and parameters), but also propagate any
    environment variable changes back to the PowerShell environment that
    called it.
.PARAMETER Path
    Path to a .bat or .cmd file.
.PARAMETER Parameters
    Parameters to pass to the batch file.
.EXAMPLE
    C:\PS> Invoke-BatchFile "$env:ProgramFiles\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
    Invokes the vcvarsall.bat file.  All environment variable changes it makes will be
    propagated to the current PowerShell session.
.NOTES
    Author: Lee Holmes
#>
function Invoke-BatchFile
{
    param([string]$Path, [string]$Parameters)

    $tempFile = [IO.Path]::GetTempFileName()

    ## Store the output of cmd.exe.  We also ask cmd.exe to output
    ## the environment table after the batch file completes
    cmd.exe /c " `"$Path`" $Parameters && set " > $tempFile

    ## Go through the environment variables in the temp file.
    ## For each of them, set the variable in our local environment.
    Get-Content $tempFile | Foreach-Object {
        if ($_ -match "^(.*?)=(.*)$") {
            Set-Content "env:\$($matches[1])" $matches[2]
        }
        else {
            $_
        }
    }

    Remove-Item $tempFile
}

$VcVars = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Auxiliary\Build\vcvarsall.bat'
Invoke-BatchFile $VcVars x64
cl hello_world.cpp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接