如何将PowerShell与Visual Studio命令提示符一起使用?


119

我已经使用Beta 2一段时间了,这让我发疯了,在运行VS2010命令提示符时,我不得不将其拖到cmd.exe。我曾经为Visual Studio 2008使用过一个不错的vsvars2008.ps1脚本。有人有vsvars2010.ps1或类似的东西吗?

Answers:


223

从这里可以自由地进行窃取: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

多年来一直有效,直到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

Visual Studio 2017的情况再次发生了变化。vsvars32.bat似乎已放弃使用VsDevCmd.bat。确切的路径可能会有所不同,具体取决于您所使用的Visual Studio 2017版本。

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

6
简要说明一下,该相同技术适用于Visual Studio2012。只需将“ Microsoft Visual Studio 10.0”更改为“ Microsoft Visual Studio 11.0”
Andy S

9
echo $Profile查看您profile.ps1的预期路径(如果您从未创建过的话
-Matt Stephenson

5
该脚本本身的运行非常出色。但是,请注意(可能):由于Visual Studio中的Package Manager Console本身是PowerShell主机,因此该脚本也将在那里运行。直到您发现“启动无需调试”或启动标准Windows控制台运行的任何其他功能或插件在PMC初始化后将无法工作之前,这似乎不是问题。我通过以下方法来解决此问题,而不是将脚本保存在“ profile.ps1”的答案中,而是将其保存到“ Microsoft.PowerShell_profile.ps1”,以便仅在“适当的” PowerShell会话中运行该脚本。
克里斯·西蒙斯

3
当存在完美的环境变量(对于VS2015为VS140COMNTOOLS)使用时,对路径进行硬编码是非常不好的做法。这甚至适用于自定义VS安装。
Voo

5
我很欣赏使用环境变量的愿望,但是这些变量似乎是由我们正试图从中提取变量的批处理文件初始化的。我很高兴看到相反的证据。在执行VsDevCmd.bat之前,我具有干净的Windows 10安装和干净的Visual Studio 2017安装,并且没有VS150COMNTOOLS环境变量。
安迪·S

26

最简单的选项是运行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
}

注意:即将在基于PowerShell Community Extensions 2.0模块的发行版中将提供此功能。


22

我在这里找到一个简单的方法:修改快捷方式。

原始的快捷方式是这样的:

%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"

如果要使其看起来更像PS,请转到快捷方式属性的“ 颜色”选项卡,然后将“红色”,“绿色”和“蓝色”值分别设置为1、36和86。

屏幕截图


直截了当,就像魅力。这个答案值得更多的赞扬。
Mark Meuer 2015年

2
对此我唯一不喜欢的是,它使冗余cmd.exe进程保持加载状态。除此之外,这是一个不错的解决方案。
orad 2015年

17

一个古老的问题,但另一个值得回答的问题(a)提供VS2013支持;(b)结合前两个答案中的最佳者;(c)提供功能包装器。

这是基于@Andy的技术(该技术以Andy表示的Allen Mack的技术为基础(又以Allen表示的Robert Anderson的技术为基础)(如用户在此页上所指出的那样,所有这些都有轻微的毛刺,被称为“ me- -”,所以我也考虑到了)))。

这是我的最终代码-请注意在正则表达式中使用非贪婪量词来处理值中可能存在的嵌入等式。这也简化了代码:单个匹配而不是匹配,然后像Andy的示例中那样拆分,或者匹配然后是indexof和子字符串,如“ 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
    }
    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
}

为了与PowerShell 2.0兼容,param部分要求[parameter(Mandatory=$true,...
2014年

1
很好,但是如果没有push / popd,imo会更好。只需使用类似cmd /c """$targetDir\vcvarsall.bat""&set"
stijn

9

Keith已经使用其Invoke-BatchFile命令提到了PowerShell社区扩展(PSCX):

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

我还注意到PSCX还具有以下Import-VisualStudioVars功能:

Import-VisualStudioVars -VisualStudioVersion 2013

4
从PSCX 3.2.0开始,此cmdlet不支持VS 2015。我为此打开了一个问题
orad 2015年

3

感谢Andy S的回答。我使用他的解决方案已有一段时间,但今天遇到了一个问题。包含等号的任何值都将被等号截断。例如,我有:

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

但是我的PS会议报告:

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

嘿,很好。也要VS2015 / 17版本更新吗?这是Google的第一个结果,我认为您的加入将对人们有所帮助。
Squirrelkiller

1

对于在2020年和Visual Studio Code 1.41.1中仍在挣扎的人,这里有点话题了。

使用上面和Internet上所有不同部分的代码,例如来自https://help.appveyor.com/discussions/questions/18777-how-to-use-vcvars64bat-from-powershell的逐步解决方法,我设法使以下脚本正常工作。

保存到VSCode“ settings.json”中,并安装了Code Runner扩展名。

使用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\""}

使用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\""}

高温超导


0

我喜欢将命令传递到子外壳中,如下所示:

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

或者

cmd /c "`"${env:VS140COMNTOOLS}..\..\VC\vcvarsall.bat`" amd64 && <someCommand> && <someOtherCommand>"  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.