webentwicklung-frage-antwort-db.com.de

Wie kann ich PowerShell mit der Eingabeaufforderung von Visual Studio verwenden?

Ich verwende Beta 2 nun schon eine Weile und es hat mich verrückt gemacht, dass ich beim Ausführen der VS2010-Eingabeaufforderung zu cmd.exe wechseln muss. Ich hatte früher ein Nice vsvars2008.ps1-Skript für Visual Studio 2008. Hat jemand eine vsvars2010.ps1 oder ähnliches?

108
Andy S

Von hier aus großzügig gestohlen: http://allen-mack.blogspot.com/2008/03/replace-visual-studio-command-Prompt.html , konnte ich dies zum Laufen bringen. Ich habe folgendes zu meinem profile.ps1 hinzugefügt und alles ist gut mit der Welt. 

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

Dies hat seit Jahren gut funktioniert - bis zu Visual Studio 2015. vcvarsall.bat existiert nicht mehr. Stattdessen können Sie die Datei vsvars32.bat verwenden, die sich im Ordner Common7\Tools befindet. 

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

Bei Visual Studio 2017 haben sich die Dinge erneut geändert. vsvars32.bat scheint zugunsten von VsDevCmd.bat fallen zu lassen. Der genaue Pfad kann je nach verwendeter Version von Visual Studio 2017 variieren. 

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
199
Andy S

Die einfachste Option ist, die VS 2010-Eingabeaufforderung auszuführen und dann PowerShell.exe zu starten. Wenn Sie dies wirklich von Ihrem "Home" -PowerShell-Prompt aus tun möchten, ist der Ansatz, den Sie zeigen, der richtige Weg. Ich benutze ein Skript, das Lee Holmes vor einiger Zeit geschrieben hat:

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

Hinweis: Diese Funktion wird in Kürze in der modulbasierten Version PowerShell Community Extensions 2.0 verfügbar sein.

24
Keith Hill

Ich habe eine einfache Methode gefunden: hier : die Verknüpfung ändern.

Die ursprüngliche Verknüpfung ist in etwa so:

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

Fügen Sie & powershell vor dem letzten Zitat hinzu:

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

Wenn Sie mehr nach PS aussehen möchten, wechseln Sie zur Registerkarte Colors der Verknüpfungseigenschaften und legen Sie die Werte für Rot, Grün und Blau auf 1, 36 bzw. 86 fest.

screenshot

16
Stijn

Eine alte Frage, die aber eine weitere Antwort wert ist, um (a) VS2013-Support bereitzustellen; (b) das Beste aus zwei vorherigen Antworten kombinieren; und (c) einen Funktionswrapper bereitstellen.

Dies baut auf @ Andys Technik auf (die auf Allen Macks Technik basiert, wie Andy es angedeutet hat) (die wiederum auf Robert Andersons Technik basiert, wie Allen es angedeutet hat) (alle hatten einen leichten Fehler, wie auf dieser Seite von dem Benutzer angegeben, der nur als "me- - ", das habe ich auch berücksichtigt))). 

Hier ist mein endgültiger Code. Beachten Sie die Verwendung des nicht-gierigen Quantifizierers im Regex, um eventuell eingebettete Gleichheitszeichen in den Werten zu behandeln. Dies geschieht auch, um den Code zu vereinfachen: Eine einzelne Übereinstimmung statt einer Übereinstimmung wird dann wie in Andys Beispiel aufgeteilt oder eine Übereinstimmung, dann Index of und Teilzeichenfolgen wie in "me -" s Beispiel).

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
}
16
Michael Sorens

Keith hat bereits die PowerShell Community Extensions (PSCX) mit dem Befehl Invoke-BatchFile erwähnt:

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

Ich habe auch bemerkt, dass PSCX auch eine Import-VisualStudioVars-Funktion hat:

Import-VisualStudioVars -VisualStudioVersion 2013
8
Tahir Hassan

Ein großes Lob an Andy S für seine Antwort. Ich habe seine Lösung schon eine Weile benutzt, aber heute bin ich auf ein Problem gestoßen. Jeder Wert, der ein Gleichheitszeichen enthält, wird am Gleichheitszeichen abgeschnitten. Zum Beispiel hatte ich:

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

Meine PS-Sitzung berichtete jedoch:

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

Ich habe dieses Problem behoben, indem ich mein Profilskript folgendermaßen geändert habe:

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
3
me--

Ich gebe gerne die Befehle an eine untergeordnete Shell:

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

Oder alternativ

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