Як я можу використовувати PowerShell за допомогою командного рядка Visual Studio?


119

Я вже деякий час використовую Beta 2, і це наштовхує мене на гайки, що мені доводиться монтувати на cmd.exe під час запуску командного рядка VS2010. У мене був гарний сценарій vsvars2008.ps1 для Visual Studio 2008. Хтось має vsvars2010.ps1 чи щось подібне?

Відповіді:


223

Крадучись звідси: http://allen-mack.blogspot.com/2008/03/replace-visual-studio-command-prompt.html , я зміг дозволити це працювати. Я додав наступне до свого профілю.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 більше не існує. Натомість ви можете використовувати файл vsvars32.bat, який знаходиться в папці 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

У 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 Studio 2012. Просто змініть "Microsoft Visual Studio 10.0" на "Microsoft Visual Studio 11.0"
Енді S

9
echo $Profileщоб побачити призначений шлях для вашого профілю.ps1, якщо ви ніколи його не створювали
Метт Стівенсон

5
Сам сценарій чудово працює. Хоча застереження (можливо): Оскільки консоль диспетчера пакунків у Visual Studio сама є хостом PowerShell, цей сценарій також буде запущений і там. Це не здається проблемою, поки ви не помітите, що "Запуск без налагодження" або будь-які інші функції або додатки, що запускають стандартну консоль Windows, не працюватимуть після ініціалізації PMC. Я працював над цим, замість того, щоб зберегти скрипт у цій відповіді на "profile.ps1", я зберег його в "Microsoft.PowerShell_profile.ps1", щоб він запускався лише у "належному" сесії PowerShell.
Кріс Сіммонс

3
Дуже погана практика жорсткого кодування шляхів, коли є ідеально чудові змінні середовища (VS140COMNTOOLS для VS2015). Це навіть буде працювати для встановлених VS встановлень.
Во

5
Я ціную бажання використовувати змінні середовища, але, здається, ці змінні ініціалізуються тим самим пакетним файлом, з якого ми намагаємося витягти змінні. Я був би радий бачити докази протилежного. У мене є чиста установка Windows 10 з чистою установкою Visual Studio 2017 і відсутність змінної середовища VS150COMNTOOLS, поки я не виконаю VsDevCmd.bat.
Енді S

26

Найпростіший варіант - запустити командний рядок VS 2010, а потім запустити PowerShell.exe. Якщо ви дійсно хочете зробити це з вашого домашнього запиту 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 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 відповідно.

скріншот


Безпосередньо і працює як шарм. Ця відповідь заслуговує на більшу кількість відгуків.
Марк Меуер

2
Єдине, що мені не подобається в цьому, це те, що він зберігає надлишковий процес cmd.exe. Крім того, це приємне рішення.
орад

17

Старе запитання, але варте іншої відповіді на (a) надання підтримки VS2013; (b) поєднати найкраще з двох попередніх відповідей; і (c) забезпечити функціональну обгортку.

Це ґрунтується на техніці @ Andy (яка спирається на техніку Аллена Мака, як вказав Енді (що, в свою чергу, базується на техніці Роберта Андерсона, як вказав Аллен (все це мало невеликі збої, як зазначено на цій сторінці користувачем, відомим лише як "me- - ", тож я і це врахував))).

Ось мій підсумковий код - зверніть увагу на використання не жадібного квантора в регулярному виразі для обробки будь-яких можливих вбудованих рівних значень. Це також трапляється для спрощення коду: один матч замість відповідності розбивається, як у прикладі Енді, або збіг, а потім 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 парам-секція вимагає [parameter(Mandatory=$true,...
sakra

1
Добре, але було б приємніше без pushd / popd. Просто використовуйте щось подібнеcmd /c """$targetDir\vcvarsall.bat""&set"
стрім

9

Кіт вже згадав про розширення спільноти PowerShell (PSCX) зі своєю Invoke-BatchFileкомандою:

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, VS 2015 не підтримується в цьому командлеті. Я відкрив для цього питання .
орад

3

Кудос Енді С. за його відповідь. Я деякий час використовую його рішення, але сьогодні зіткнувся з проблемою. Будь-яке значення, в якому є знак рівності, усічене у знака рівності. Наприклад, у мене було:

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

Але мій сеанс роботи з ПС повідомив:

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, я думаю, що ваше доповнення допоможе людям.
Білочка в

1

Для тих, хто все ще бореться з цим у 2020 році та Visual Studio Code 1.41.1, тож тут трохи теми.

Використовуючи всі різні частини коду зверху та Інтернет, наприклад, https://help.appveyor.com/discussions/questions/18777-how-to-use-vcvars64bat-from-powershell, і з покроковим підходом мені вдалося працює нижче сценарій.

Збережено у VSCode "settings.json" та із встановленим розширенням Code Runner.

Завдяки Microsoft (R) 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 (R) 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\""}

HTH


0

Мені подобається передавати команди в дочірню оболонку так:

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

Або в якості альтернативи

cmd /c "`"${env:VS140COMNTOOLS}..\..\VC\vcvarsall.bat`" amd64 && <someCommand> && <someOtherCommand>"  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.