如何在 VisualStudio 命令提示符中使用 PowerShell?

我使用 Beta 2已经有一段时间了,当我运行 Visual Studio 2010命令提示符时,我不得不把它放到 cmd.exe 中,这让我非常抓狂。我曾经为 VisualStudio2008准备了一个不错的 Vsvars2008.ps1脚本。是否有 Vsvars2010.ps1脚本或类似的东西?

54839 次浏览

从博客文章 用 PowerShell 替换 Visual Studio 命令提示符中随意地窃取信息,我得以让它工作。我添加了以下到我的 简介 ps1文件,一切都很好与世界。

pushd 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC'
cmd /c "vcvarsall.bat&set" |
foreach {
if ($_ -match "=") {
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])"  -value "$($v[1])"
}
}
popd
write-host "`nVisual Studio 2010 Command Prompt variables set." -ForegroundColor Yellow

多年来,这种方法一直运行良好——直到 VisualStudio2015年。Vcvarsall.bat已经不存在了。相反,您可以使用位于 Common7 Tools 文件夹中的 Vsvars32.bat文件。

pushd 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools'
cmd /c "vsvars32.bat&set" |
foreach {
if ($_ -match "=") {
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])"  -value "$($v[1])"
}
}
popd
write-host "`nVisual Studio 2015 Command Prompt variables set." -ForegroundColor Yellow

VisualStudio2017的情况又发生了变化。vsvars32.bat看起来已经被 VsDevCmd.bat取代了。确切的路径可能会因您使用的 VisualStudio2017版本而有所不同。

pushd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools"
cmd /c "VsDevCmd.bat&set" |
foreach {
if ($_ -match "=") {
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])"  -value "$($v[1])"
}
}
popd
Write-Host "`nVisual Studio 2017 Command Prompt variables set." -ForegroundColor Yellow

你也可以让分割只创建两个项目,以避免破坏包括等号在内的值,等号也是环境变量名称和值的分隔符:

$v = $_.split("=", 2); set-item -force -path "ENV:\$($v[0])"  -value

由于 VisualStudio2022是64位的,因此对它进行了一些小的更改。

pushd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools"
cmd /c "VsDevCmd.bat&set" |
foreach {
if ($_ -match "=") {
$v = $_.split("=", 2); set-item -force -path "ENV:\$($v[0])"  -value "$($v[1])"
}
}
popd
Write-Host "`nVisual Studio 2022 Command Prompt variables set." -ForegroundColor Yellow

最简单的选择是运行 VS 2010命令提示符,然后启动 PowerShell.exe。如果您真的想从您的“ home”PowerShell 提示符中完成这项工作,那么您展示的方法就是正确的方法。我用的是李 · 福尔摩斯前阵子写的一个剧本:

<#
.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:VS90COMNTOOLS\..\..\vc\vcvarsall.bat"
Invokes the vcvarsall.bat file to set up a 32-bit dev environment.  All
environment variable changes it makes will be propagated to the current
PowerShell session.
.EXAMPLE
C:\PS> Invoke-BatchFile "$env:VS90COMNTOOLS\..\..\vc\vcvarsall.bat" amd64
Invokes the vcvarsall.bat file to set up a 64-bit dev environment.  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]
}
}


Remove-Item $tempFile
}

注意: 这个功能将在即将发布的基于 PowerShell 社区扩展2.0模块的版本中提供。

Andy S 的回答致敬。我用他的方法有一段时间了,但今天遇到了一个问题。任何包含等号的值都被截断为等号。例如,我有:

JAVA_TOOL_OPTIONS=-Duser.home=C:\Users\Me

但是我的 PowerShell 会议报告说:

PS C:\> $env:JAVA_TOOL_OPTIONS


-Duser.home

我通过修改配置文件脚本来解决这个问题:

pushd 'c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC'
cmd /c "vcvarsall.bat&set" |
foreach {
if ($_ -match "=") {
$i = $_.indexof("=")
$k = $_.substring(0, $i)
$v = $_.substring($i + 1)
Set-Item -force -path "ENV:\$k"  -value "$v"
}
}
popd

(a)提供 VisualStudio2013支持; (b)综合前面两个答案中的最佳答案; 以及(c)提供函数包装器:

这是建立在 Andy 的技巧的基础上的(Andy 的技巧建立在 Allen Mack 的技术之上,就像 Andy 指出的那样(依次建立在 Robert Anderson 的技术之上,就像 Allen 指出的那样(所有这些技术都有一个小小的故障,用户在这个页面上只说了“ me ——”,所以我也考虑到了这一点))。

下面是我的最后一段代码——请注意正则表达式中使用了非贪婪量化符来处理值中可能嵌入的等于。这也简化了代码: 一个单一的匹配,而不是像 Andy 的例子那样分割一个匹配,或者像“ me ——”的例子那样分割一个匹配,然后是 索引和子字符串)。

function Set-VsCmd
{
param(
[parameter(Mandatory, HelpMessage="Enter VS version as 2010, 2012, or 2013")]
[ValidateSet(2010,2012,2013)]
[int]$version
)
$VS_VERSION = @{ 2010 = "10.0"; 2012 = "11.0"; 2013 = "12.0" }
$targetDir = "c:\Program Files (x86)\Microsoft Visual Studio $($VS_VERSION[$version])\VC"
if (!(Test-Path (Join-Path $targetDir "vcvarsall.bat"))) {
"Error: Visual Studio $version not installed"
return
}
Push-Location $targetDir
cmd /c "vcvarsall.bat&set" |
foreach {
if ($_ -match "(.*?)=(.*)") {
Set-Item -force -path "ENV:\$($matches[1])" -value "$($matches[2])"
}
}
Pop-Location
Write-Host "`nVisual Studio $version Command Prompt variables set." -ForegroundColor Yellow
}

我找到了一个简单的方法 给你: 修改快捷方式。

最初的捷径是这样的:

%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat""

在最后一个引用之前添加 & powershell,如下所示:

%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat" & powershell"

如果您想让它看起来更像 PowerShell,请转到快捷方式属性的 颜色选项卡,并将红色、绿色和蓝色值分别设置为1、36和86。

Screenshot

Keith 已经提到过 PowerShell 社区扩展(PSCX) ,它的 Invoke-BatchFile命令是:

Invoke-BatchFile "${env:ProgramFiles(x86)}\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"

我还注意到 PSCX 还有一个 Import-VisualStudioVars功能:

Import-VisualStudioVars -VisualStudioVersion 2013

我喜欢像这样将命令传递到子 shell 中:

cmd /c "`"${env:VS140COMNTOOLS}vsvars32.bat`" && <someCommand>"

或者说

cmd /c "`"${env:VS140COMNTOOLS}..\..\VC\vcvarsall.bat`" amd64 && <someCommand> && <someOtherCommand>"

对于那些仍在2020年和 Visual Studio Code 1.41.1中挣扎的人来说,这有点跑题了。

使用从以前的答案和互联网的所有不同部分的代码,例如,从 如何使用 PowerShell 中的 vcvars64.bat和一步一步的方法,我设法使下面的脚本工作。

保存到 Visual Studio Code“ setings.json”并安装了 Code Runner 扩展。

使用 Microsoft (注册商标) C/C + + 编译器最佳化版本“ cl.exe”,来自 Visual Studio 2015/14.0:

"code-runner.runInTerminal": true,
"code-runner.executorMap": {
"cpp": "cd $dir; pushd \"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\"; cmd.exe /c \"call vcvarsall.bat x86_amd64 & set > %temp%\\vcvars.txt\"; Get-Content \"$env:temp\\vcvars.txt\" | Foreach-Object { if ($_ -match \"^(.*?)=(.*)$\") {   Set-Content \"env:\\$($matches[1])\" $matches[2]  }}; popd; cls; cl *.cpp; .\\\"$fileNameWithoutExt.exe\"; Write-Host -NoNewLine 'Press any key to continue...';  $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); del \"$fileNameWithoutExt.exe\"; del \"$fileNameWithoutExt.obj\""}

使用 Microsoft (注册商标)的 C/C + + 编译器最佳化版本“ cl.exe”,来自 Visual Studio 2019/16.4.3:

"code-runner.runInTerminal": true,
"code-runner.executorMap": {
"cpp": "cd $dir; pushd \"c:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\"; cmd.exe /c \"call vcvarsall.bat x86_amd64 & set > %temp%\\vcvars.txt\"; Get-Content \"$env:temp\\vcvars.txt\" | Foreach-Object { if ($_ -match \"^(.*?)=(.*)$\") {   Set-Content \"env:\\$($matches[1])\" $matches[2]  }}; popd; cls; cl *.cpp; .\\\"$fileNameWithoutExt.exe\"; Write-Host -NoNewLine 'Press any key to continue...';  $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); del \"$fileNameWithoutExt.exe\"; del \"$fileNameWithoutExt.obj\""}

作为 Andy S 的回答的扩展,此更新针对 VisualStudio2019社区版。然而,我还需要64位,所以这包括 -arch=amd64-host_arch=amd64标志以及任何人需要它们。

pushd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools"
cmd /c "VsDevCmd.bat -arch=amd64 -host_arch=amd64&set " |
foreach {
if ($_ -match "=") {
$v = $_.split("="); set-item -force -path "ENV:\$($v[0])"  -value "$($v[1])"
}
}
popd
Write-Host "`nVisual Studio 2019 Command Prompt variables set." -ForegroundColor Yellow

首先,检查这个文件夹的内容:

C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances/

里面会有另一个文件夹,名字是十六进制数字(例如 2a7a9ed6,但是 对于不同的 MSVC 版本,< strong > 将改变 )。我称之为 <instance_id>

然后从 PowerShell 运行:

Import-Module 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll'; Enter-VsDevShell <instance_id> -DevCmdArguments '-arch=x64'

或者您可以使用以下 target创建一个快捷方式:

<path to your powershell.exe> -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell <instance_id> -DevCmdArguments '-arch=x64'}"

显然,如果需要 x86工具集,请删除 -arch=x64

事实上,我们有一个简单而干净的方法来做到这一点。

众所周知,在 shell 中启动的子 shell 会自动继承父 shell 的变量。因此,我们只需要在 PowerShell 中启动 CMD,执行 vcvars64.bat,然后在这个 CMD 中再次启动 PowerShell。

Visual Studio 2019:

cmd /K '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" && powershell.exe'

如果你使用的是 PowerShell Core:

cmd /K '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" && pwsh.exe'

你可以把它包装成一个函数,放在 Powershell 配置文件(所有用户的 $PSHOME\Microsoft.PowerShell_profile.ps1)中:

function vcvars64 {
cmd /K '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" && powershell.exe'
}

或者如果你正在使用 PowerShell 核心:

function vcvars64 {
cmd /K '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" && pwsh.exe'
}

然后在 PowerShell 中简单地执行 vcvars64:

PS C:\Users\Glavo> cl
cl: The term 'cl' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
PS C:\Users\Glavo> vcvars64
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.11.5
** Copyright (c) 2021 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
PowerShell 7.1.5
Copyright (c) Microsoft Corporation.


https://aka.ms/powershell
Type 'help' to get help.


PS C:\Users\Glavo> cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30136 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.


usage: cl [ option... ] filename... [ /link linkoption... ]

而不是

  1. 调用 Batch 脚本
  2. 写下环境变量
  3. 使用 VisualStudio2022(可能还有2019)以如此复杂的方式执行修改,您可以使用以下更简单的方法
Import-Module "VS-Directory\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
Enter-VsDevShell -VsInstallPath "VS-Directory\Community" -DevCmdArguments

但是,如果希望在 VS 中默认使用64位 MSVC 和环境,则可以使用 arch = 64的 DevCmdArguments

Enter-VsDevShell -VsInstallPath "VS-Directory\Community" -DevCmdArguments '-arch=x64'

使用“模块”和 VsDevShell更加简单和干净。下面是一个简单的 Powershell 脚本,适用于 MSVC 和 Clang:

param(
[String] $Compiler = "MSVC"
)


if ($Compiler -ne "MSVC" -and $Compiler -ne "Clang") {
Write-Error "Unknown compiler '$Compiler'; must be MSVC or Clang"
Exit -1
}


Write-Host "======================================="
Write-Host "Setting up environment variables..."


# Visual Studio path <https://github.com/microsoft/vswhere/wiki/Find-VC>
$vsPath = &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationpath


Write-Host "Microsoft Visual Studio path = '$vsPath'"


# Use module `Microsoft.VisualStudio.DevShell.dll`
Import-Module (Get-ChildItem $vsPath -Recurse -File -Filter Microsoft.VisualStudio.DevShell.dll).FullName


Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation -DevCmdArguments '-arch=x64'


# NOTE: `-DevCmdArguments` are arguments to `vsdevcmd.bat`


# Select compiler
if ($Compiler -eq "MSVC") {
$_Compiler = "MSVC"
Set-Item -Path "env:CC" -Value "cl.exe"
Set-Item -Path "env:CXX" -Value "cl.exe"
}
elseif ($Compiler -eq "Clang") {
$_Compiler = "Clang"
Set-Item -Path "env:CC" -Value "clang-cl.exe"
Set-Item -Path "env:CXX" -Value "clang-cl.exe"
}


Write-Host "Selecting $_Compiler as C/C++ compiler."
Write-Host "======================================="

尝试使用 Powershell 模块 Posh-vsdev。它甚至似乎支持多个已安装版本的 VisualStudio。

Install-Module -Name posh-vsdev -Scope CurrentUser


# Import the posh-vsdev module module
Import-Module posh-vsdev


# Get all installed Visual Studio instances
Get-VisualStudioVersion


# Get a specific version
Get-VisualStudioVersion -Version 14


# Use the Developer Command Prompt Environment
Use-VisualStudioEnvironment


# Restore the non-Developer environment
Reset-VisualStudioEnvironment


# Reset cache of Visual Studio instances
Reset-VisualStudioVersionCache


# Add posh-vsdev to your PowerShell profile
Add-VisualStudioEnvironmentToProfile -UseEnvironment

要使用开发工具 env 启动任何最新的 PowerShell:

C:/Program Files/PowerShell/7/pwsh.exe -noe -c "&{Import-Module """C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell 5f8ef82b}"

如果它不工作,通过快速启动菜单搜索寻找 VS 2019开发者 PowerShell-> 右键单击 物业-> 复制 目标行-> 更改 exe 路径到所需的 PowerShell.exe

也可以像您选择的 Editor/IDE 那样启动它 Vscode 示例:

"terminal.integrated.profiles.windows": {
"win_dev_shell_64": {
"path": "C:/Program Files/PowerShell/7/pwsh.exe",
"args": [
"-noe",
"-c",
"&{Import-Module \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\Tools\\Microsoft.VisualStudio.DevShell.dll\"; Enter-VsDevShell 5f8ef82b}"
]
}
},
"terminal.integrated.defaultProfile.windows": "win_dev_shell_64",