web-dev-qa-db-fra.com

Comment utiliser PowerShell avec l'invite de commandes Visual Studio?

J'utilise la version bêta 2 depuis un moment maintenant et cela me rend fou que je dois bousculer CMD.exe lors de l'exécution de l'invite de commande VS2010. J'avais un script Nice vsvars2008.ps1 pour Visual Studio 2008. Quelqu'un a-t-il un vsvars2010.ps1 ou quelque chose de similaire?

108
Andy S

Voler généreusement à partir d'ici: http://allen-mack.blogspot.com/2008/03/replace-visual-studio-command-Prompt.html , j'ai pu le faire fonctionner. J'ai ajouté ce qui suit à mon profil.ps1 et tout va bien dans le monde. 

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

Cela a bien fonctionné pendant des années - jusqu'à Visual Studio 2015. Le fichier vcvarsall.bat n'existe plus. À la place, vous pouvez utiliser le fichier vsvars32.bat, situé dans le dossier 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

Les choses ont encore changé pour Visual Studio 2017. vsvars32.bat semble avoir été abandonné au profit de VsDevCmd.bat. Le chemin exact peut varier en fonction de l'édition de Visual Studio 2017 que vous utilisez. 

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

L'option la plus simple consiste à exécuter l'invite de commande VS 2010, puis à démarrer PowerShell.exe. Si vous voulez vraiment faire cela à partir de votre invite PowerShell "à la maison", l’approche que vous montrez est la voie à suivre. J'utilise un script que Lee Holmes a écrit il y a longtemps:

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

Remarque: cette fonction sera disponible prochainement dans la version basée sur le module PowerShell Community Extensions 2.0.

24
Keith Hill

J'ai trouvé une méthode simple ici : modifier le raccourci.

Le raccourci original ressemble à ceci:

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

Ajoutez & powershell avant le dernier devis, comme ceci:

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

Si vous souhaitez le rapprocher de PS, accédez à l'onglet Couleurs des propriétés du raccourci et définissez les valeurs Rouge, Vert et Bleu sur 1, 36 et 86 respectivement.

screenshot

16
Stijn

Une vieille question, mais qui mérite une autre réponse à (a) fournir le support VS2013; (b) combinez le meilleur de deux réponses précédentes; et (c) fournir un wrapper de fonction.

Ceci s'appuie sur la technique de @ Andy (qui s'appuie sur la technique d'Allen Mack, comme l'indique Andy (qui à son tour s'appuie sur la technique de Robert Anderson, telle qu'indiquée par Allen) - ", alors j'ai pris cela en compte aussi))). 

Voici mon code final - notez l'utilisation du quantificateur non-glouton dans la regex pour gérer tous les égaux incorporés possibles dans les valeurs. Cela simplifie également le code: une seule correspondance au lieu d’une correspondance est ensuite scindée comme dans l’exemple d’Andy ou une concordance suivie d’indexof et de sous-chaînes comme dans l’exemple "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
}
16
Michael Sorens

Keith a déjà mentionné les extensions de communauté PowerShell (PSCX), avec sa commande Invoke-BatchFile:

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

J'ai aussi remarqué que PSCX a aussi une fonction Import-VisualStudioVars:

Import-VisualStudioVars -VisualStudioVersion 2013
8
Tahir Hassan

Bravo à Andy S pour sa réponse. J'utilise sa solution depuis un moment, mais j'ai rencontré un problème aujourd'hui. Toute valeur comportant un signe égal est tronquée au niveau du signe égal. Par exemple, j'avais:

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

Mais ma session PS a rapporté:

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

J'ai résolu ce problème en modifiant mon script de profil comme suit:

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

J'aime passer les commandes dans un shell enfant comme ceci:

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

Ou bien

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