visual-studio 如何在 Visual Studio 命令提示符下使用 PowerShell?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2124753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use PowerShell with the Visual Studio Command Prompt?
提问by Andy S
I've been using Beta 2 for a while now and it's been driving me nuts that I have to punt to cmd.exe when running the VS2010 Command Prompt. I used to have a nice vsvars2008.ps1 script for Visual Studio 2008. Anyone have a vsvars2010.ps1 or something similar?
我已经使用 Beta 2 有一段时间了,当运行 VS2010 命令提示符时,我不得不转向 cmd.exe,这让我很抓狂。我曾经有一个很好的 vsvars2008.ps1 脚本用于 Visual Studio 2008。有人有 vsvars2010.ps1 或类似的东西吗?
回答by Andy S
Stealing liberally from here: http://allen-mack.blogspot.com/2008/03/replace-visual-studio-command-prompt.html, I was able to get this to work. I added the following to my profile.ps1 and all is well with the world.
从这里大量窃取:http: //allen-mack.blogspot.com/2008/03/replace-visual-studio-command-prompt.html,我能够让它工作。我将以下内容添加到我的 profile.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
This has worked well for years - until Visual Studio 2015. vcvarsall.bat no longer exists. Instead, you can use the vsvars32.bat file, which is located in the Common7\Tools folder.
这多年来一直运行良好 - 直到 Visual Studio 2015。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
Things have changed yet again for Visual Studio 2017. vsvars32.batappears to have been dropped in favor of VsDevCmd.bat. The exact path may vary depending on which edition of Visual Studio 2017 you're using.
Visual Studio 2017 的情况再次发生了变化。vsvars32.bat似乎已经放弃了VsDevCmd.bat. 确切路径可能因您使用的 Visual Studio 2017 版本而异。
pushd "C:\Program Files (x86)\Microsoft Visual Studio17\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
回答by Keith Hill
The simplest option is to run the VS 2010 command prompt and then start PowerShell.exe. If you really want to do this from your "home" PowerShell prompt, the approach you show is the way to go. I use a script that Lee Holmes wrote a while back:
最简单的选择是运行 VS 2010 命令提示符,然后启动 PowerShell.exe。如果您真的想从“主页”PowerShell 提示符执行此操作,那么您展示的方法就是要走的路。我使用了 Lee Holmes 不久前写的一个脚本:
<#
.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
}
Note: this function will be available in the PowerShell Community Extensions2.0 module-based release coming soon.
注意:此功能将在即将推出的基于模块的PowerShell Community Extensions2.0 版本中提供。
回答by user247702
I found a simple method here: modify the shortcut.
我在这里找到了一个简单的方法:修改快捷方式。
The original shortcut is something like this:
原来的快捷方式是这样的:
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat""
Add & powershellbefore the last quote, like this:
& powershell在最后一个引用之前添加,如下所示:
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat" & powershell"
If you want to make it look more like PS, go to the Colorstab of the shortcut properties and set the Red, Green and Blue values to 1, 36 and 86 respectively.
如果想让它看起来更像 PS,请转到快捷方式属性的“颜色”选项卡,将红色、绿色和蓝色值分别设置为 1、36 和 86。
回答by Michael Sorens
An old question but worth another answer to (a) provide VS2013 suppport; (b) combine the best of two previous answers; and (c) provide a function wrapper.
一个老问题,但值得另一个答案 (a) 提供 VS2013 支持;(b) 结合之前两个答案中最好的一个;(c) 提供一个函数包装器。
This builds on @Andy's technique (which builds on Allen Mack's technique as Andy indicated (which in turn builds on Robert Anderson's technique as Allen indicated (all of which had a slight glitch as indicated on this page by the user known only as "me--", so I took that into account as well))).
这建立在@Andy 的技术上(它建立在安迪指出的艾伦麦克的技术上(这反过来又建立在艾伦指出的罗伯特·安德森的技术上(所有这些都有一个小故障,如用户在此页面上所指出的,该用户仅称为“我- -”,所以我也考虑到了)))。
Here is my final code--note the use of the non-greedy quantifier in the regex to handle any possible embedded equals in the values. That also happens to simplify the code: a single match instead of a match then split as in Andy's example or a match then indexof and substrings as in "me--"'s example).
这是我的最终代码——注意在正则表达式中使用非贪婪量词来处理值中任何可能的嵌入等于。这也恰好简化了代码:单个匹配而不是匹配然后像 Andy 的示例中那样拆分,或者匹配然后像“me--”的示例中那样使用 indexof 和子字符串)。
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
}
pushd $targetDir
cmd /c "vcvarsall.bat&set" |
foreach {
if ($_ -match "(.*?)=(.*)") {
Set-Item -force -path "ENV:$($matches[1])" -value "$($matches[2])"
}
}
popd
write-host "`nVisual Studio $version Command Prompt variables set." -ForegroundColor Yellow
}
回答by Tahir Hassan
Keith has already mentioned PowerShell Community Extensions (PSCX), with its Invoke-BatchFilecommand:
Keith 已经提到了 PowerShell Community Extensions (PSCX),它的Invoke-BatchFile命令是:
Invoke-BatchFile "${env:ProgramFiles(x86)}\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
I also noticed that PSCX also has an Import-VisualStudioVarsfunction:
我还注意到 PSCX 还有一个Import-VisualStudioVars功能:
Import-VisualStudioVars -VisualStudioVersion 2013
回答by me--
Kudos to Andy S for his answer. I've been using his solution for a while, but ran into a problem today. Any value that has an equals sign in it is truncated at the equals sign. For example, I had:
感谢 Andy S 的回答。我一直在使用他的解决方案一段时间,但今天遇到了一个问题。任何带有等号的值都会在等号处被截断。例如,我有:
JAVA_TOOL_OPTIONS=-Duser.home=C:\Users\Me
But my PS session reported:
但我的 PS 会话报告:
PS C:\> $env:JAVA_TOOL_OPTIONS
-Duser.home
I fixed this by modifying my profile script to the following:
我通过将我的配置文件脚本修改为以下内容来解决此问题:
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
回答by olin000
For someone who is still struggling with it in 2020 and Visual Studio Code 1.41.1, so a bit off topic here.
对于在 2020 年和 Visual Studio Code 1.41.1 中仍在苦苦挣扎的人来说,这里有点跑题了。
Using all different parts of code from above and the Internet e.g. from https://help.appveyor.com/discussions/questions/18777-how-to-use-vcvars64bat-from-powershelland with a step by step approach I managed to have the below script working.
使用上面和互联网上的所有不同部分的代码,例如来自https://help.appveyor.com/discussions/questions/18777-how-to-use-vcvars64bat-from-powershell并通过一步一步的方法我设法有下面的脚本工作。
Saved into VSCode "settings.json" and with the Code Runner extension installed.
保存到 VSCode“settings.json”并安装了 Code Runner 扩展。
With Microsoft (R) C/C++ Optimizing Compiler Version "cl.exe" from Visual Studio 2015/14.0:
使用来自 Visual Studio 2015/14.0 的 Microsoft (R) C/C++ 优化编译器版本“cl.exe”:
"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\""}
With Microsoft (R) C/C++ Optimizing Compiler Version "cl.exe" from Visual Studio 2019/16.4.3:
使用来自 Visual Studio 2019/16.4.3 的 Microsoft (R) C/C++ 优化编译器版本“cl.exe”:
"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\""}
HTH
HTH
回答by MatrixManAtYrService
I like to pass the commands into a child shell like so:
我喜欢将命令传递到子 shell 中,如下所示:
cmd /c "`"${env:VS140COMNTOOLS}vsvars32.bat`" && <someCommand>"
Or alternatively
或者替代地
cmd /c "`"${env:VS140COMNTOOLS}..\..\VC\vcvarsall.bat`" amd64 && <someCommand> && <someOtherCommand>"


