Bagaimana cara menggunakan PowerShell dengan Visual Studio Command Prompt?

119

Saya telah menggunakan Beta 2 untuk sementara waktu sekarang dan itu membuat saya gila bahwa saya harus memutar ke cmd.exe saat menjalankan Command Prompt VS2010. Saya dulu memiliki skrip vsvars2008.ps1 yang bagus untuk Visual Studio 2008. Ada yang punya vsvars2010.ps1 atau yang serupa?

Andy S
sumber

Jawaban:

223

Mencuri secara bebas dari sini: http://allen-mack.blogspot.com/2008/03/replace-visual-studio-command-prompt.html , saya bisa membuatnya bekerja. Saya menambahkan yang berikut ini ke profile.ps1 saya dan semuanya baik-baik saja dengan dunia.

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

Ini telah bekerja dengan baik selama bertahun-tahun - hingga Visual Studio 2015. vcvarsall.bat tidak ada lagi. Sebagai gantinya, Anda dapat menggunakan file vsvars32.bat, yang terletak di folder 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

Hal-hal telah berubah lagi untuk Visual Studio 2017. vsvars32.battampaknya telah dibatalkan VsDevCmd.bat. Jalur persisnya mungkin berbeda-beda bergantung pada edisi Visual Studio 2017 yang Anda gunakan.

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
Andy S
sumber
6
Hanya catatan singkat bahwa teknik yang sama ini bekerja untuk Visual Studio 2012. Cukup ubah "Microsoft Visual Studio 10.0" menjadi "Microsoft Visual Studio 11.0"
Andy S
9
echo $Profileuntuk melihat jalur yang dimaksudkan untuk profile.ps1 Anda, jika Anda belum pernah membuatnya
Matt Stephenson
5
Skrip itu sendiri bekerja dengan sangat baik. Catatan hati-hati, meskipun (mungkin): Karena Konsol Manajer Paket di Visual Studio itu sendiri adalah host PowerShell, skrip ini akan dijalankan di sana juga. Ini tampaknya tidak menjadi masalah sampai Anda melihat bahwa "Jalankan tanpa debugging" atau fungsi atau plugin lain yang menjalankan konsol Windows standar tidak akan berfungsi setelah PMC diinisialisasi. Saya mengatasi ini dengan, alih-alih menyimpan skrip dalam jawaban ini ke "profile.ps1", saya menyimpannya ke "Microsoft.PowerShell_profile.ps1" sehingga hanya dijalankan dalam sesi PowerShell yang "tepat".
Chris Simmons
3
Ini benar-benar praktik yang buruk untuk melakukan hardcode jalur ketika ada variabel lingkungan yang sangat baik (VS140COMNTOOLS untuk VS2015) untuk digunakan. Itu bahkan akan berfungsi untuk pemasangan VS khusus.
Voo
5
Saya menghargai keinginan untuk menggunakan variabel lingkungan, tetapi variabel tersebut tampaknya diinisialisasi oleh file batch yang kami coba ekstrak dari variabel. Saya akan senang melihat bukti yang sebaliknya. Saya memiliki instalasi Windows 10 yang bersih dengan instalasi Visual Studio 2017 yang bersih dan tidak ada variabel lingkungan VS150COMNTOOLS sampai saya mengeksekusi VsDevCmd.bat.
Andy S
26

Opsi paling sederhana adalah menjalankan command prompt VS 2010 dan kemudian menjalankan PowerShell.exe. Jika Anda benar-benar ingin melakukan ini dari prompt PowerShell "rumah", pendekatan yang Anda tunjukkan adalah cara yang tepat. Saya menggunakan skrip yang ditulis Lee Holmes beberapa waktu lalu:

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

Catatan: fungsi ini akan tersedia dalam rilis berbasis modul PowerShell Community Extensions 2.0 segera.

Keith Hill
sumber
22

Saya menemukan metode sederhana di sini : ubah pintasan.

Pintasan aslinya adalah seperti ini:

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

Tambahkan & powershellsebelum kutipan terakhir, seperti ini:

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

Jika Anda ingin membuatnya terlihat lebih seperti PS, buka tab Warna pada properti pintasan dan atur nilai Merah, Hijau, dan Biru menjadi 1, 36 dan 86.

tangkapan layar

pengguna247702
sumber
Lugas dan bekerja seperti pesona. Jawaban ini membutuhkan lebih banyak suara positif.
Mark Meuer
2
Satu-satunya hal yang saya tidak suka tentang ini, adalah itu membuat proses cmd.exe berlebihan dimuat. Selain itu adalah solusi yang bagus.
orad
17

Sebuah pertanyaan lama tetapi layak untuk dijawab dengan (a) memberikan dukungan VS2013; (b) menggabungkan yang terbaik dari dua jawaban sebelumnya; dan (c) menyediakan pembungkus fungsi.

Ini dibangun di atas teknik @ Andy (yang dibangun di atas teknik Allen Mack seperti yang ditunjukkan Andy (yang kemudian dikembangkan dari teknik Robert Anderson seperti yang ditunjukkan Allen (semuanya memiliki sedikit kesalahan seperti yang ditunjukkan di halaman ini oleh pengguna yang hanya dikenal sebagai "saya) - ", jadi saya memperhitungkannya juga))).

Ini adalah kode terakhir saya - perhatikan penggunaan pembilang non-serakah di regex untuk menangani kemungkinan yang sama yang disematkan dalam nilainya. Itu juga terjadi untuk menyederhanakan kode: satu kecocokan, bukan kecocokan, lalu pisahkan seperti pada contoh Andy atau kecocokan lalu indeks dan substring seperti dalam contoh "saya -").

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
}
Michael Sorens
sumber
Untuk kompatibilitas PowerShell 2.0, bagian param memerlukan [parameter(Mandatory=$true,...
sakra
1
Bagus, tapi saya akan lebih baik tanpa pushd / popd. Cukup gunakan sesuatu seperticmd /c """$targetDir\vcvarsall.bat""&set"
stijn
9

Keith telah menyebutkan PowerShell Community Extensions (PSCX), dengan Invoke-BatchFileperintahnya:

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

Saya juga memperhatikan bahwa PSCX juga memiliki Import-VisualStudioVarsfungsi:

Import-VisualStudioVars -VisualStudioVersion 2013
Tahir Hassan
sumber
4
Mulai PSCX 3.2.0, VS 2015 tidak didukung di cmdlet ini. Saya membuka masalah untuk itu.
orad
3

Kudos to Andy S untuk jawabannya. Saya telah menggunakan solusinya untuk sementara waktu, tetapi mengalami masalah hari ini. Nilai apa pun yang memiliki tanda sama dengan di dalamnya dipotong pada tanda sama dengan. Misalnya, saya punya:

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

Tetapi sesi PS saya melaporkan:

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

Saya memperbaikinya dengan mengubah skrip profil saya menjadi yang berikut:

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
saya--
sumber
Hei tambahan yang bagus. Perbarui dengan versi VS2015 / 17 juga? Ini adalah hasil Google pertama, saya rasa penambahan Anda akan membantu orang.
Squirrelkiller
1

Untuk seseorang yang masih berjuang dengan itu di tahun 2020 dan Visual Studio Code 1.41.1, jadi sedikit keluar dari topik di sini.

Menggunakan semua bagian kode yang berbeda dari atas dan Internet misalnya dari https://help.appveyor.com/discussions/questions/18777-how-to-use-vcvars64bat-from-powershell dan dengan pendekatan langkah demi langkah saya berhasil memiliki skrip di bawah ini berfungsi.

Disimpan ke VSCode "settings.json" dan dengan ekstensi Code Runner diinstal.

Dengan Microsoft (R) C / C ++ Optimizing Compiler Version "cl.exe" dari 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\""}

Dengan Microsoft (R) C / C ++ Mengoptimalkan Versi Kompilator "cl.exe" dari 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

olin000
sumber
0

Saya suka meneruskan perintah ke cangkang anak seperti ini:

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

Atau sebaliknya

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