Camino a MSBuild

¿Cómo puedo obtener programáticamente la ruta a MSBuild desde un equipo donde se ejecuta mi .exe?

Puedo obtener la versión .NET del entorno, pero ¿hay alguna manera de obtener la carpeta correcta para una versión .NET?

Hurgando en el registro, parece

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\2.0 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\3.5 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0 

puede ser lo que buscas; encienda regedit.exe y eche un vistazo.

También puede imprimir la ruta de MSBuild.exe a la línea de comando:

 reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath 

Para scripts de shell cmd en Windows 7, utilizo el siguiente fragmento en mi archivo por lotes para encontrar MSBuild.exe en .NET Framework versión 4. Supongo que la versión 4 está presente, pero no asumo la subversión. Esto no es totalmente de propósito general, pero para los scripts rápidos puede ser útil:

 set msbuild.exe= for /D %%D in (%SYSTEMROOT%\Microsoft.NET\Framework\v4*) do set msbuild.exe=%%D\MSBuild.exe 

Para mis usos, estoy saliendo del archivo por lotes con un error si eso no funcionó:

 if not defined msbuild.exe echo error: can't find MSBuild.exe & goto :eof if not exist "%msbuild.exe%" echo error: %msbuild.exe%: not found & goto :eof 

Si desea utilizar MSBuild para .Net 4, puede usar el siguiente comando de PowerShell para obtener la ruta del ejecutable. Si desea la versión 2.0 o 3.5, simplemente cambie la variable $ dotNetVersion.

Para ejecutar el ejecutable, deberá anteponer la variable $ msbuild con &. Eso ejecutará la variable.

 # valid versions are [2.0, 3.5, 4.0] $dotNetVersion = "4.0" $regKey = "HKLM:\software\Microsoft\MSBuild\ToolsVersions\$dotNetVersion" $regProperty = "MSBuildToolsPath" $msbuildExe = join-path -path (Get-ItemProperty $regKey).$regProperty -childpath "msbuild.exe" &$msbuildExe 

@AllenSanborn tiene una excelente versión de PowerShell, pero algunas personas tienen el requisito de utilizar solo scripts por lotes para comstackciones.

Esta es una versión aplicada de lo que respondió @ bono8106.

msbuildpath.bat

 @echo off reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath > nul 2>&1 if ERRORLEVEL 1 goto MissingMSBuildRegistry for /f "skip=2 tokens=2,*" %%A in ('reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath') do SET "MSBUILDDIR=%%B" IF NOT EXIST "%MSBUILDDIR%" goto MissingMSBuildToolsPath IF NOT EXIST "%MSBUILDDIR%msbuild.exe" goto MissingMSBuildExe exit /b 0 goto:eof ::ERRORS ::--------------------- :MissingMSBuildRegistry echo Cannot obtain path to MSBuild tools from registry goto:eof :MissingMSBuildToolsPath echo The MSBuild tools path from the registry '%MSBUILDDIR%' does not exist goto:eof :MissingMSBuildExe echo The MSBuild executable could not be found at '%MSBUILDDIR%' goto:eof 

build.bat

 @echo off call msbuildpath.bat "%MSBUILDDIR%msbuild.exe" foo.csproj /p:Configuration=Release 

Para Visual Studio 2017 / MSBuild 15, Aziz Atif (el tipo que escribió Elmah ) escribió un script por lotes

 build.cmd Release Foo.csproj 

https://github.com/linqpadless/LinqPadless/blob/master/build.cmd

 @echo off setlocal if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles% if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)% for %%e in (Community Professional Enterprise) do ( if exist "%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" ( set "MSBUILD=%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" ) ) if exist "%MSBUILD%" goto :restre set MSBUILD= for %%i in (MSBuild.exe) do set MSBUILD=%%~dpnx$PATH:i if not defined MSBUILD goto :nomsbuild set MSBUILD_VERSION_MAJOR= set MSBUILD_VERSION_MINOR= for /f "delims=. tokens=1,2,3,4" %%m in ('msbuild /version /nologo') do ( set MSBUILD_VERSION_MAJOR=%%m set MSBUILD_VERSION_MINOR=%%n ) if not defined MSBUILD_VERSION_MAJOR goto :nomsbuild if not defined MSBUILD_VERSION_MINOR goto :nomsbuild if %MSBUILD_VERSION_MAJOR% lss 15 goto :nomsbuild if %MSBUILD_VERSION_MINOR% lss 1 goto :nomsbuild :restre for %%i in (NuGet.exe) do set nuget=%%~dpnx$PATH:i if "%nuget%"=="" ( echo WARNING! NuGet executable not found in PATH so build may fail! echo For more on NuGet, see https://github.com/nuget/home ) pushd "%~dp0" nuget restre ^ && call :build Debug %* ^ && call :build Release %* popd goto :EOF :build setlocal "%MSBUILD%" /p:Configuration=%1 /v:m %2 %3 %4 %5 %6 %7 %8 %9 goto :EOF :nomsbuild echo Microsoft Build version 15.1 (or later) does not appear to be echo installed on this machine, which is required to build the solution. exit /b 1 

Puede utilizar este mismo comando de prueba de PowerShell para obtener MSBuildToolsPath del registro.

PowerShell (del registro)

 Resolve-Path HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\* | Get-ItemProperty -Name MSBuildToolsPath 

Salida

 MSBuildToolsPath : C:\Program Files (x86)\MSBuild\12.0\bin\amd64\ PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\12.0 PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions PSChildName : 12.0 PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry MSBuildToolsPath : C:\Program Files (x86)\MSBuild\14.0\bin\amd64\ PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0 PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions PSChildName : 14.0 PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry MSBuildToolsPath : C:\Windows\Microsoft.NET\Framework64\v2.0.50727\ PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\2.0 PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions PSChildName : 2.0 PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry MSBuildToolsPath : C:\Windows\Microsoft.NET\Framework64\v3.5\ PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\3.5 PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions PSChildName : 3.5 PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry MSBuildToolsPath : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0 PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions PSChildName : 4.0 PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry 

o desde el sistema de archivos

PowerShell (del sistema de archivos)

 Resolve-Path "C:\Program Files (x86)\MSBuild\*\Bin\amd64\MSBuild.exe" Resolve-Path "C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe" 

Salida

 Path ---- C:\Program Files (x86)\MSBuild\12.0\Bin\amd64\MSBuild.exe C:\Program Files (x86)\MSBuild\14.0\Bin\amd64\MSBuild.exe C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe 

Las ubicaciones de registro

 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\2.0 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\3.5 

dar la ubicación para el ejecutable.

Pero si necesita la ubicación donde guardar las extensiones de la Tarea, está en

 %ProgramFiles%\MSBuild 

Esto funciona para Visual Studio 2015 y 2017:

 function Get-MSBuild-Path { $vs14key = "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" $vs15key = "HKLM:\SOFTWARE\wow6432node\Microsoft\VisualStudio\SxS\VS7" $msbuildPath = "" if (Test-Path $vs14key) { $key = Get-ItemProperty $vs14key $subkey = $key.MSBuildToolsPath if ($subkey) { $msbuildPath = Join-Path $subkey "msbuild.exe" } } if (Test-Path $vs15key) { $key = Get-ItemProperty $vs15key $subkey = $key."15.0" if ($subkey) { $msbuildPath = Join-Path $subkey "MSBuild\15.0\bin\amd64\msbuild.exe" } } return $msbuildPath } 

la manera más fácil podría ser abrir PowerShell e ingresar

 dir HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\ 

En Windows 2003 y posterior, escriba este comando en cmd:

 cmd> where MSBuild Sample result: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe 

Si no aparece nada, significa que .NET Framework no está incluido en el sistema PATH. El MSBuild debe estar en la carpeta de instalación .NET, junto con los comstackdores .NET (vbc.exe, csc.exe)

Comenzando con MSBuild 2017 (v15), MSBuild ahora está instalado en una carpeta debajo de cada versión de Visual Studio, y ya no está configurado en el registro

Estos son algunos ejemplos de dónde se encuentra MSBuild.exe en mi máquina:

 C:\windows\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe (v2.0.50727.8745 32-bit) C:\windows\Microsoft.NET\Framework64\v2.0.50727\MSBuild.exe (v2.0.50727.8745 64-bit) C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe (v3.5.30729.8763 32-bit) C:\Windows\Microsoft.NET\Framework64\v3.5\MSBuild.exe (v3.5.30729.8763 64-bit) C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe (v4.7.2053.0 32-bit) C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe (v4.7.2053.0 64-bit) C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe (v12.0.21005.1 32-bit) C:\Program Files (x86)\MSBuild\12.0\Bin\amd64\MSBuild.exe (v12.0.21005.1 64-bit) C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe (v14.0.25420.1 32-bit) C:\Program Files (x86)\MSBuild\14.0\Bin\amd64\MSBuild.exe (v14.0.25420.1 64-bit) C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe (v15.1.1012+g251a9aec17 32-bit) C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\amd64\MSBuild.exe (v15.1.1012+g251a9aec17 64-bit) C:\Program Files (x86)\Microsoft Visual Studio\2017\{LicenceName}\MSBuild\Bin\MSBuild.exe (v15.1.1012.6693 32-bit) C:\Program Files (x86)\Microsoft Visual Studio\2017\{LicenceName}\MSBuild\Bin\amd64\MSBuild.exe (v15.1.1012.6693 64-bit) 

Para recuperar la ruta de msbuild 15 (Visual Studio 2017) con lotes del registro sin herramientas adicionales:

 set regKey=HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7 set regValue=15.0 for /f "skip=2 tokens=3,*" %%A in ('reg.exe query %regKey% /v %regValue% 2^>nul') do ( set vs17path=%%A %%B ) set msbuild15path = %vs17path%\MSBuild\15.0\Bin\MSBuild.exe 

Mejores herramientas disponibles:

  • vswhere : localice Visual Studio 2017 y las instalaciones más nuevas, consulte get msbuild15 path with batch (utiliza la ruta codificada como mi fragmento de código anterior).
  • Visual Studio Setup PowerShell Module utilizando Microsoft.VisualStudio.Workload.MSBuildTools

Puede obtener la versión .NET y obtener una versión específica:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ MSBuild \ ToolsVersions

Es la ubicación del registro

Con Visual Studio 2017, Microsoft cambió nuevamente la ubicación de MSBuild. Esta vez fue tan difícil localizarlo que creó una herramienta ad-hoc para esta tarea:

Visual Studio Locator

Parece que esta será la forma “correcta” de descubrir MSBuild, al menos para VS2017

Si desea comstackr un proyecto Delphi, consulte “ERROR MSB4040 No hay un objective en el proyecto” cuando se usa msbuild + Delphi2009

Se dice la respuesta correcta: “Hay un archivo por lotes llamado rsvars.bat ( búscalo en la carpeta RAD Studio). Llama antes de llamar a MSBuild y configurará las variables de entorno necesarias. Asegúrate de que las carpetas estén correctas en rsvars. .bat si tiene el comstackdor en una ubicación diferente a la predeterminada “.

Este bate no solo actualizará la variable de entorno PATH a la carpeta .NET adecuada con la versión adecuada de MSBuild.exe, sino que también registrará otras variables necesarias.