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

在Windows PowerShell中运行VS 2017生成工具,windows,visual-studio,powershell,batch-file,environment-variables,Windows,Visual Studio,Powershell,Batch File,Environment Variables,我不喜欢IDE,所以我安装了VS2017构建工具,这样我可以通过命令行工作 安装进行得很顺利,一切都使用Windows CMD,但是PowerShell要好得多,我更喜欢使用PS。这里的问题是: VisualC++命令行工具使用路径、TMP、包含、LIB和LIPATH环境变量,也可以使用工具特定的环境变量。由于这些环境变量的值特定于您的安装,并且可以通过产品更新或升级进行更改,因此建议您使用vcvarsall.bat或开发人员命令提示符快捷方式,而不是自己设置它们。有关编译器和链接器使用的特定

我不喜欢IDE,所以我安装了VS2017构建工具,这样我可以通过命令行工作

安装进行得很顺利,一切都使用Windows CMD,但是PowerShell要好得多,我更喜欢使用PS。这里的问题是:

VisualC++命令行工具使用路径、TMP、包含、LIB和LIPATH环境变量,也可以使用工具特定的环境变量。由于这些环境变量的值特定于您的安装,并且可以通过产品更新或升级进行更改,因此建议您使用vcvarsall.bat或开发人员命令提示符快捷方式,而不是自己设置它们。有关编译器和链接器使用的特定环境变量的信息,请参阅CL环境变量和链接环境变量

我不应该自己设置环境变量,这对我来说很好,唯一的问题是当我在PS中运行
vcvvarsall.bat
时,环境变量没有变化。我是PS新手,所以我猜
.bat
文件不能改变会话环境变量。如果是这样的话,那么我就无法计算出PS。作为一个旁注,
CL
LINK
变量永远不会出现,我将在下面解释

我想我应该找出变量是什么。我
echo
在运行
batch
文件之前和之后,将所有变量都放到一个文本文件中,并编写了一个简短的Java程序来查找任何新的或修改的内容。这些是。如您所见,
CL
LINK
变量不存在

我如何解决这个问题?我想写我自己的
批处理
文件,但是如果第一个文件不起作用,为什么我的呢?我在附加的MSDN页面上没有看到任何内容,也没有看到任何关于如何使PowerShell工作的链接。

编写一个批处理文件,1)调用
vcvvarsall.bat
,2)调用PowerShell,就像这样(此文件特定于VS 2015):

%*
允许我们向该文件传递与向
vcvvarsall.bat
传递相同的参数

然后,PowerShell将在为其准备好环境块的情况下运行。另一种方法不起作用,因为PowerShell本身不执行批处理文件——它依赖于
cmd
来执行,并且作为一个子进程,它有自己的环境块,不反映在其父进程上。

调用批处理文件“$env:ProgramFiles\Microsoft Visual Studio 9.0\VC\vcvarsall.bat”
<#
.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
调用vcvarsall.bat文件。它所做的所有环境变量更改都将 已传播到当前PowerShell会话。 .注释 作者:李·霍姆斯 #> 函数调用批处理文件 { 参数([string]$Path,[string]$Parameters) $tempFile=[IO.Path]::GetTempFileName() ##存储cmd.exe的输出。我们还要求cmd.exe进行输出 ##批处理文件完成后的环境表 cmd.exe/c“`$Path`“$Parameters&&set”>$tempFile ##检查临时文件中的环境变量。 ##对于它们中的每一个,在本地环境中设置变量。 获取内容$tempFile | Foreach对象{ 如果($匹配“^(.*)=(.*)$”){ 设置内容“环境:\$($matches[1])”$matches[2] } 否则{ $_ } } 删除项$tempFile } $VcVars='C:\ProgramFiles(x86)\Microsoft Visual Studio\2019\Preview\VC\Auxiliary\Build\vcvarsall.bat' 调用批处理文件$VcVars x64 cl hello_world.cpp
您链接的MSDN页面上对
CL环境变量
链接环境变量
的引用是链接。您是否跟随他们查看他们添加了什么?编写一个批处理文件,1)调用
vcvvarsall.bat
,2)调用PowerShell。然后,PowerShell将在为其准备好环境块的情况下运行。另一种方法不起作用,因为PowerShell本身不执行批处理文件——它依赖
cmd
来执行,并且作为子进程,它有自己的环境块,不反映在其父级上。@KenWhite都应该添加相同名称的变量:
CL
\u CL
LINK
\u LINK
。这些都没有出现,这就是我的意思。您应该使用的当前版本,其中您可能会注意到,CL工具使用CL环境变量(如果定义为在命令前添加内容),因此,如果没有定义任何内容,它就不会在命令前面加上任何内容。@Jeroenmoster我编写了批处理文件:但它似乎不起作用。如果我双击它,一个命令会弹出一秒钟,说环境已初始化,然后消失,什么也没发生。此外,如果我在CMD会话中运行批处理文件,它的作用与双击它相同,甚至不会在CMD中打开PS。对于VS2017构建工具,调用路径是
C:\Program Files(x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat
<#
.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