Làm cách nào để sử dụng PowerShell với Visual Studio Command Prompt?


119

Tôi đã sử dụng Beta 2 một thời gian và nó khiến tôi phát điên khi phải chuyển sang cmd.exe khi chạy VS2010 Command Prompt. Tôi đã từng có tập lệnh vsvars2008.ps1 đẹp cho Visual Studio 2008. Có ai có vsvars2010.ps1 hoặc thứ gì đó tương tự không?

Câu trả lời:


223

Ăn cắp một cách tự do từ đây: http://allen-mack.blogspot.com/2008/03/replace-visual-studio-command-prompt.html , tôi đã có thể làm cho điều này hoạt động. Tôi đã thêm phần sau vào profile.ps1 của mình và tất cả đều tốt với thế giới.

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

Điều này đã hoạt động tốt trong nhiều năm - cho đến khi Visual Studio 2015. vcvarsall.bat không còn tồn tại. Thay vào đó, bạn có thể sử dụng tệp vsvars32.bat, nằm trong thư mục Common7 \ Tools.

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

Mọi thứ đã thay đổi một lần nữa đối với Visual Studio 2017. Có vsvars32.batvẻ như đã bị loại bỏ VsDevCmd.bat. Đường dẫn chính xác có thể khác nhau tùy thuộc vào phiên bản Visual Studio 2017 bạn đang sử dụng.

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
Chỉ cần một lưu ý nhanh chóng mà kỹ thuật này cùng làm việc cho Visual Studio 2012. Đơn giản chỉ cần thay đổi "Microsoft Visual Studio 10.0" thành "Microsoft Visual Studio 11.0"
Andy S

9
echo $Profileđể xem đường dẫn dự định cho hồ sơ của bạn.ps1, nếu bạn chưa bao giờ tạo nó
Matt Stephenson

5
Bản thân kịch bản hoạt động tuyệt vời. Tuy nhiên, một lưu ý thận trọng (có thể): Vì Bảng điều khiển Trình quản lý Gói trong Visual Studio tự nó là một máy chủ PowerShell, tập lệnh này cũng sẽ chạy ở đó. Điều này dường như không phải là vấn đề cho đến khi bạn nhận thấy rằng "Chạy mà không gỡ lỗi" hoặc bất kỳ chức năng hoặc plugin nào khác chạy khởi chạy bảng điều khiển Windows tiêu chuẩn sẽ không hoạt động sau khi PMC được khởi chạy. Tôi đã giải quyết vấn đề này bằng cách, thay vì lưu tập lệnh trong câu trả lời này vào "profile.ps1", tôi đã lưu nó vào "Microsoft.PowerShell_profile.ps1" để nó chỉ được chạy trong một phiên PowerShell "thích hợp".
Chris Simmons

3
Thực sự không tốt khi mã hóa các đường dẫn khi có các biến môi trường hoàn toàn tốt (VS140COMNTOOLS cho VS2015) để sử dụng. Điều đó thậm chí sẽ hoạt động đối với cài đặt VS tùy chỉnh.
Voo

5
Tôi đánh giá cao mong muốn sử dụng các biến môi trường, nhưng các biến đó dường như được khởi tạo bằng chính tệp lô mà chúng tôi đang cố gắng trích xuất các biến từ đó. Tôi sẽ rất vui khi thấy bằng chứng ngược lại. Tôi có bản cài đặt Windows 10 sạch với bản cài đặt Visual Studio 2017 sạch và không có biến môi trường VS150COMNTOOLS cho đến khi tôi thực thi VsDevCmd.bat.
Andy S

26

Tùy chọn đơn giản nhất là chạy dấu nhắc lệnh VS 2010 và sau đó khởi động PowerShell.exe. Nếu bạn thực sự muốn thực hiện việc này từ lời nhắc PowerShell "tại nhà" của mình, thì cách tiếp cận bạn chỉ ra là cách để thực hiện. Tôi sử dụng một kịch bản mà Lee Holmes đã viết trước đây:

<#
.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
}

Lưu ý: chức năng này sẽ có sẵn trong bản phát hành dựa trên mô-đun PowerShell Community Extensions 2.0 sắp ra mắt.


22

Tôi đã tìm thấy một phương pháp đơn giản ở đây : sửa đổi phím tắt.

Phím tắt ban đầu giống như sau:

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

Thêm vào & powershelltrước câu trích dẫn cuối cùng, như thế này:

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

Nếu bạn muốn làm cho nó trông giống PS hơn, hãy chuyển đến tab Màu sắc của thuộc tính phím tắt và đặt các giá trị Đỏ, Xanh lục và Xanh lam tương ứng là 1, 36 và 86.

ảnh chụp màn hình


Thẳng thắn và làm việc như một sự quyến rũ. Câu trả lời này xứng đáng nhận được nhiều ủng hộ hơn.
Mark Meuer

2
Điều duy nhất tôi không thích về điều này là nó giữ một tiến trình cmd.exe dư thừa được tải. Khác hơn đó là một giải pháp tốt đẹp.
orad

17

Một câu hỏi cũ nhưng đáng để trả lời khác cho (a) cung cấp hỗ trợ VS2013; (b) kết hợp câu trả lời đúng nhất của hai câu trả lời trước đó; và (c) cung cấp một trình bao bọc hàm.

Điều này được xây dựng dựa trên kỹ thuật của @ Andy (dựa trên kỹ thuật của Allen Mack như Andy đã chỉ ra (lần lượt được xây dựng dựa trên kỹ thuật của Robert Anderson như Allen đã chỉ ra (tất cả đều có một chút trục trặc như được chỉ ra trên trang này bởi người dùng chỉ được gọi là "tôi- - “, nên tôi cũng tính đến chuyện đó))).

Đây là mã cuối cùng của tôi - lưu ý việc sử dụng bộ định lượng không tham lam trong regex để xử lý bất kỳ giá trị nào có thể được nhúng vào. Điều đó cũng xảy ra để đơn giản hóa mã: một kết hợp đơn lẻ thay vì một kết hợp sau đó tách ra như trong ví dụ của Andy hoặc một kết hợp rồi lập chỉ mục và chuỗi con như trong ví dụ của "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
}

Để tương thích PowerShell 2.0, phần param yêu cầu [parameter(Mandatory=$true,...
sakra

1
Đẹp, nhưng liệu imo sẽ đẹp hơn nếu không có pushd / popd. Chỉ cần sử dụng một cái gì đó giống nhưcmd /c """$targetDir\vcvarsall.bat""&set"
Stijn

9

Keith đã đề cập đến Tiện ích mở rộng cộng đồng PowerShell (PSCX), với Invoke-BatchFilelệnh của nó :

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

Tôi cũng nhận thấy rằng PSCX cũng có một Import-VisualStudioVarschức năng:

Import-VisualStudioVars -VisualStudioVersion 2013

4
Kể từ PSCX 3.2.0, VS 2015 không được hỗ trợ trong lệnh ghép ngắn này. Tôi đã mở một vấn đề cho nó.
orad

3

Kudo cho Andy S vì câu trả lời của anh ấy. Tôi đã sử dụng giải pháp của anh ấy một thời gian, nhưng hôm nay gặp sự cố. Bất kỳ giá trị nào có dấu bằng trong đó sẽ bị cắt ngắn ở dấu bằng. Ví dụ, tôi đã có:

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

Nhưng phiên PS của tôi đã báo cáo:

PS C:\> $env:JAVA_TOOL_OPTIONS
-Duser.home

Tôi đã sửa lỗi này bằng cách sửa đổi tập lệnh tiểu sử của mình thành như sau:

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

Này, bổ sung tốt đẹp. Cập nhật nó với các phiên bản VS2015 / 17 ? Đây là kết quả google đầu tiên, tôi nghĩ sự bổ sung của bạn sẽ giúp ích cho mọi người.
Squirrelkiller

1

Đối với một người vẫn đang đấu tranh với nó vào năm 2020 và Visual Studio Code 1.41.1, vì vậy một chút lạc đề ở đây.

Sử dụng tất cả các phần khác nhau của mã từ trên và Internet, ví dụ như từ https://help.appveyor.com/discussions/questions/18777-how-to-use-vcvars64bat-from-powershell và với cách tiếp cận từng bước, tôi đã quản lý có tập lệnh dưới đây hoạt động.

Đã lưu vào VSCode "settings.json" và với phần mở rộng Code Runner được cài đặt.

Với Microsoft (R) C / C ++ Tối ưu hóa phiên bản trình biên dịch "cl.exe" từ 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\""}

Với Microsoft (R) C / C ++ Tối ưu hóa phiên bản trình biên dịch "cl.exe" từ 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\""}

HTH


0

Tôi muốn chuyển các lệnh vào một shell con như vậy:

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

Hay cách khác

cmd /c "`"${env:VS140COMNTOOLS}..\..\VC\vcvarsall.bat`" amd64 && <someCommand> && <someOtherCommand>"  
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.