Camino a MSBuild

186

¿Cómo puedo obtener programáticamente la ruta a MSBuild desde una máquina donde se está ejecutando mi .exe?

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

dagda1
fuente

Respuestas:

141

Buscando en el registro, parece que

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.

Consulta a través de la línea de comando (según Nikolay Botev )

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

Consulta a través de PowerShell (por MovGP0 )

dir HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\
Brian
fuente
55
Instalé Visual Studio 2017 RC e inicié el Símbolo del sistema del desarrollador, la versión de MSBuild es 15. +, pero esta versión no se muestra en el registro. ¿Cómo obtengo acceso al mismo MSBuild que está utilizando el Dev Cmd Prompt?
SuperJMN
66
MSBuild 15 se encuentra en `C: \ Archivos de programa (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ amd64`
nZeus
2
Solo si instaló VS2017 allí, no pude encontrar un solo punto de entrada en el registro de MsBuildToolsPath para el conjunto de herramientas 15.0
Paciv
8
docs.microsoft.com/en-us/visualstudio/msbuild/… "MSBuild ahora está instalado en una carpeta en cada versión de Visual Studio. Por ejemplo, C: \ Archivos de programa (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild "y" Los valores de ToolsVersion ya no se establecen en el registro "
Hulvej
2
@ORMapper Microsoft ofrece un proyecto en GitHub para determinar las rutas de las instancias de Visual Studio 2017 / msbuild 15.x. Es un único ejecutable que puede ser utilizado por su software / scripts de compilación.
Roi Danton
140

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
Nikolay Botev
fuente
1
Tenga en cuenta que si desea crear una aplicación de Windows Phone, que necesita el msbuild de 32 bits. Consultar el registro solo proporciona el msbuild de 64 bits en una máquina de 64 bits.
Victor Ionescu
2
@VictorIonescu: puede usar /reg:32o /reg:64en ambos bits de cmd(o cualquier proceso que esté ejecutando) para obtener explícitamente esa ruta.
Simon Buchan el
esto le dará el camino a una ubicación antigua (4.0): la que probablemente desee esté en otro lugar, consulte stackoverflow.com/questions/32007871/…
JonnyRaa
En mi caso estaba bajoComputer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath
Sen Jacob
32

Si desea usar 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
fuente
2
funciona también para $dotNetVersion12.0 (vs 2013) y 14.0 (vs 2015) (si está instalado, por supuesto)
Julian
44
No funciona para VS 2017, que no agrega un valor debajo de la HKLM:\software\Microsoft\MSBuild\ToolsVersionsclave. En su lugar, necesita obtener el directorio de instalación VS2017 HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStud‌​io\SxS\VS7\15.0, luego agregar MSBuild\15.0\Bin\MSBuild.exepara obtener la ubicación de MSBuild EXE.
Ian Kemp
30

Para las secuencias de comandos de shell de 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 uso general, pero para 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, salgo 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
yoyó
fuente
@yoyo ¿Para qué set bb.build.msbuild.exe=? ¿Es necesario o solo un artefacto de su configuración?
Elisée
@ Elisée Oops, lo siento, es un error tipográfico copiar / pegar. En mi entorno, llamo a la variable bb.build.msbuild.exe, no solucioné esa instancia cuando pegué la respuesta. Solucionado ahora, gracias por señalarlo.
yoyo
26

Puede usar este comando PowerShell de prueba para obtener MSBuildToolsPathel 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 del 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
dhcgn
fuente
1
La mejor respuesta sobre este tema.
Teoman shipahi
21

Instrucciones para encontrar MSBuild :

  • Potencia Shell: &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe
  • CMD: "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe

Instrucciones para encontrar VSTest :

  • Potencia Shell: &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -find Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe
  • CMD: "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -find Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe

(Tenga en cuenta que las instrucciones anteriores están ligeramente modificadas de las oficiales de Microsoft. En particular, he incluido el -prereleaseindicador para permitir que se recojan las instalaciones de Vista previa y RC, y -products *para detectar las instalaciones de Visual Studio Build Tools).


Solo tomó más de dos años, pero finalmente en 2019, Microsoft nos escuchó y nos dio una forma de encontrar estos ejecutables vitales . Si tiene instalado Visual Studio 2017 y / o 2019, vswherese puede consultar la utilidad para conocer la ubicación de MSBuild et al. Como vswhere siempre se encuentra en %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe , ya no se requiere bootstrapping ni se requiere hardcoding de ruta.

La magia es el -findparámetro, agregado en la versión 2.6.2 . Puede determinar la versión que ha instalado ejecutando vswhereo comprobando sus propiedades de archivo. Si tiene una versión anterior, simplemente puede descargar la última y sobrescribir la existente %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe.

vswhere.exees un ejecutable independiente, por lo que puede descargarlo y ejecutarlo desde cualquier lugar donde tenga una conexión a Internet. Eso significa que sus scripts de compilación pueden verificar si el entorno en el que se ejecutan está configurado correctamente, por nombrar una opción.

Ian Kemp
fuente
Ya hay 3 respuestas que mencionan vswhere, incluido su comentario a tal efecto en una de ellas. Agregar esta respuesta solo empeora la sopa de respuestas.
jpaugh
44
4 ahora. Encontré esta respuesta útil, mientras que no encontré las otras respuestas de vswhere útiles.
cowlinator
Vale la pena señalar que solo porque VSWHERE dice que es el msbuild.exe que se debe usar, no significa que si escribe msbuilden la línea de comando (especialmente la línea de comando de Visual Studio si la usa), esa es la que se usará. Para ver lo que se utiliza si escribe msbuilden la línea de comandos, haga lo siguiente: where msbuild. Si eso no informa lo mismo que VSWHERE dice que lo último y lo mejor es, entonces debe hacer una ruta completa a la msbuild.exeque desea usar, o hacer ajustes a sus variables PATH para adaptarse.
Jinlye
Entonces, la siguiente pregunta es cómo encontrar el camino a donde sea ...
BJury
17

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

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 :restore
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
:restore
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 restore ^
 && 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
JJS
fuente
2
Nota: Dado que VS2017 / msbuild 15.x no usa el registro para sus rutas, vswhere es una alternativa para determinar la ruta de msbuild.
Roi Danton
1
Además, AzizAtif es el hombre. Eche un vistazo a esto para las versiones 15.1 - github.com/linqpadless/LinqPadless/blob/master/build.cmd
JJS
2
Además, vswhere se puede instalar a través de Chocolatey: chocolatey.org/packages/vswhere
cowlinator
6

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

}
Raman Zhylich
fuente
3
Para Build Tools, use vswhere -products *, como se especifica en github.com/Microsoft/vswhere/wiki/Find-MSBuild .
TN.
Para vswhere, debe conocer la ruta donde se encuentra. Y, por supuesto, debe tener power-shell disponible para su sistema de compilación. Solo una pregunta: ¿por qué amd64? ¿Tiene algo específico para construir?
Maxim
Votado porque esta solución esencialmente solo usa una clave de registro para MSBuild 15 también, no una biblioteca o script de terceros. Por curiosidad, ¿a qué se refiere "SxS \ VS7"? ¿Eso seguirá siendo válido en las versiones VS?
Lazlo
5

Las ubicaciones del registro

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

Indique la ubicación del ejecutable.

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

%ProgramFiles%\MSBuild
Paulo Santos
fuente
44
Es bastante viejo, lo sé, pero de todos modos: en x64-Systems, la carpeta MSBuild se encuentra en ProgramFiles (x86)
Sascha
4

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

dir HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\
MovGP0
fuente
4

Una frase basada en la respuesta de @ dh_cgn :

(Resolve-Path ([io.path]::combine(${env:ProgramFiles(x86)}, 'Microsoft Visual Studio', '*', '*', 'MSBuild', '*' , 'bin' , 'msbuild.exe'))).Path

Selecciona todas las rutas existentes, por ejemplo, rutas. C:\Program Files (x86)\Microsoft Visual Studio\*\*\MSBuild\*\bin\msbuild.exe.

Las estrellas comodines son:

  • el año (2017)
  • la edición visual studio (comunidad, profesional, empresa)
  • la versión de herramientas (15.0)

Tenga en cuenta que este comando está seleccionando la primera ruta que coincide con la expresión ordenada por alfabeto. Para reducirlo, simplemente reemplace los comodines con elementos específicos, por ejemplo. El año o la versión de herramientas.

Serio
fuente
3

En Windows 2003 y versiones posteriores, 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 la RUTA del sistema. MSBuild debe estar en la carpeta de instalación de .NET, junto con los compiladores de .NET (vbc.exe, csc.exe)

draganicimw
fuente
Esta respuesta no agrega mucho sobre otras respuestas. Es menos robusto que esta respuesta
jpaugh
3

A partir de MSBuild 2017 (v15), MSBuild ahora está instalado en una carpeta en cada versión de Visual Studio

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)
cowlinator
fuente
De acuerdo con una respuesta anterior de 2017 lo hace en la tienda hecho de esta información en el registro.
jpaugh
2

Para recuperar la ruta de msbuild 15 (Visual Studio 2017) con lote 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:

Roi Danton
fuente
1
me salvaste la vida
Hakan Fıstık
Ya hay una versión de PowerShell de esto. Alrededor de 2017, ¿hay alguna razón para evitar aprender Powershell?
jpaugh
2
@jpaugh No todos los sistemas de compilación tienen PowerShell disponible.
Roi Danton el
1

No pensaría que hay mucho que agregar aquí, pero tal vez es hora de una forma unificada de hacerlo en todas las versiones. Combiné el enfoque de consulta del registro (VS2015 y posteriores) con el uso de vswhere (VS2017 y posteriores) para llegar a esto:

function Find-MsBuild {
    Write-Host "Using VSWhere to find msbuild..."
    $path = & $vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe | select-object -first 1

    if (!$path) {
        Write-Host "No results from VSWhere, using registry key query to find msbuild (note this will find pre-VS2017 versions)..."
        $path = Resolve-Path HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\* |
                    Get-ItemProperty -Name MSBuildToolsPath |
                    sort -Property @{ Expression={ [double]::Parse($_.PSChildName) }; Descending=$true } |
                    select -exp MSBuildToolsPath -First 1 |
                    Join-Path -ChildPath "msbuild.exe"
    }

    if (!$path) {
        throw "Unable to find path to msbuild.exe"
    }

    if (!(Test-Path $path)) {
        throw "Found path to msbuild as $path, but file does not exist there"
    }

    Write-Host "Using MSBuild at $path..."
    return $path
}
Neil Barnwell
fuente
1

Hay muchas respuestas correctas. Sin embargo, aquí utilizo One-Liner en PowerShell para determinar la ruta de MSBuild para la versión más reciente :

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\' | 
    Get-ItemProperty -Name MSBuildToolsPath | 
    Sort-Object PSChildName | 
    Select-Object -ExpandProperty MSBuildToolsPath -first 1
Martin Brandl
fuente
+1 ¡Realmente útil! Pero en mi respuesta uso -last 1(en lugar de -first 1para obtener la última versión) y también concatena el nombre del archivo (para obtener correctamente la ruta completa y no solo la carpeta).
Mariano Desanze
1

Este método de PowerShell obtiene la ruta a msBuild desde múltiples fuentes. Intentando en orden:

  1. Primero usando vswhere (porque Visual Studio parece tener versiones más actualizadas de msBuild) ej.

    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe
  2. Si no se encuentra probando el registro (versión de marco), por ejemplo

    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe

Código Powershell:

Function GetMsBuildPath {

    Function GetMsBuildPathFromVswhere {
        # Based on https://github.com/microsoft/vswhere/wiki/Find-MSBuild/62adac8eb22431fa91d94e03503d76d48a74939c
        $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
        $path = & $vswhere -latest -prerelease -products * -requires Microsoft.Component.MSBuild -property installationPath
        if ($path) {
            $tool = join-path $path 'MSBuild\Current\Bin\MSBuild.exe'
            if (test-path $tool) {
                return $tool
            }
            $tool = join-path $path 'MSBuild\15.0\Bin\MSBuild.exe'
            if (test-path $tool) {
                return $tool
            }
        }
    }

    Function GetMsBuildPathFromRegistry {
        # Based on Martin Brandl's answer: https://stackoverflow.com/a/57214958/146513
        $msBuildDir = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\' |
            Get-ItemProperty -Name MSBuildToolsPath |
            Sort-Object PSChildName |
            Select-Object -ExpandProperty MSBuildToolsPath -last 1
        $msBuildPath = join-path $msBuildDir 'msbuild.exe'
        if (test-path $msBuildPath) {
            return $msBuildPath
        }
    }

    $msBuildPath = GetMsBuildPathFromVswhere
    if (-Not $msBuildPath) {
        $msBuildPath = GetMsBuildPathFromRegistry
    }
    return $msBuildPath
}
Mariano Desanze
fuente
0

Para Visual Studio 2017 sin conocer la edición exacta, puede usar esto en un script por lotes:

FOR /F "tokens=* USEBACKQ" %%F IN (`where /r "%PROGRAMFILES(x86)%\Microsoft Visual 
Studio\2017" msbuild.exe ^| findstr /v /i "amd64"`) DO (SET msbuildpath=%%F)

El comando findtr es ignorar ciertos ejecutables de msbuild (en este ejemplo, el amd64).

Ernstjan Freriks
fuente
0

agregar rama de vswhere para https://github.com/linqpadless/LinqPadless/blob/master/build.cmd , funciona bien en mi computadora, y la rama de vswhere funciona en la computadora de mi compañero. Puede ser, la rama vswhere debería avanzar como la primera comprobación.

@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 :build

for /f "usebackq tokens=1* delims=: " %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.Component.MSBuild`) do (
  if /i "%%i"=="installationPath" set InstallDir=%%j
)

if exist "%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe" (
  set "MSBUILD=%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe"
)
if exist "%MSBUILD%" goto :build
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
)
echo %MSBUILD_VERSION_MAJOR% %MSBUILD_VERSION_MINOR%
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
:restore
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"
popd
goto :EOF

:build
setlocal
"%MSBUILD%" -restore -maxcpucount %1 /p:Configuration=%2 /v:m %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
Shamork.Fu
fuente
0

Obtenga la última versión de MsBuild. La mejor manera, para todos los tipos de instalación de msbuild, para diferentes arquitecturas de procesador (Power Shell):

function Get-MsBuild-Path
{
    $msbuildPathes = $null
    $ptrSize = [System.IntPtr]::Size
    switch ($ptrSize) {
        4 {
            $msbuildPathes =
            @(Resolve-Path "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\*\*\MSBuild\*\Bin\msbuild.exe" -ErrorAction SilentlyContinue) +
            @(Resolve-Path "${Env:ProgramFiles(x86)}\MSBuild\*\Bin\MSBuild.exe" -ErrorAction SilentlyContinue) +
            @(Resolve-Path "${Env:windir}\Microsoft.NET\Framework\*\MSBuild.exe" -ErrorAction SilentlyContinue)
        }
        8 {
            $msbuildPathes =
            @(Resolve-Path "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\*\*\MSBuild\*\Bin\amd64\msbuild.exe" -ErrorAction SilentlyContinue) +
            @(Resolve-Path "${Env:ProgramFiles(x86)}\MSBuild\*\Bin\amd64\MSBuild.exe" -ErrorAction SilentlyContinue) +
            @(Resolve-Path "${Env:windir}\Microsoft.NET\Framework64\*\MSBuild.exe" -ErrorAction SilentlyContinue)
        }
        default {
            throw ($msgs.error_unknown_pointersize -f $ptrSize)
        }
    }

    $latestMSBuildPath = $null
    $latestVersion = $null
    foreach ($msbuildFile in $msbuildPathes)
    {
        $msbuildPath = $msbuildFile.Path
        $versionOutput = & $msbuildPath -version
        $fileVersion = (New-Object System.Version($versionOutput[$versionOutput.Length - 1]))
        if (!$latestVersion -or $latestVersion -lt $fileVersion)
        {
            $latestVersion = $fileVersion
            $latestMSBuildPath = $msbuildPath
        }
    }

    Write-Host "MSBuild version detected: $latestVersion" -Foreground Yellow
    Write-Host "MSBuild path: $latestMSBuildPath" -Foreground Yellow

    return $latestMSBuildPath;
}
Stas BZ
fuente
-2

Si desea compilar un proyecto de Delphi, mire "ERROR MSB4040 No hay objetivo en el proyecto" cuando use msbuild + Delphi2009

La respuesta correcta se dice: "Hay un archivo por lotes llamado rsvars.bat (búsquelo en la carpeta RAD Studio). Llame a eso antes de llamar a MSBuild, y configurará las variables de entorno necesarias. Asegúrese de que las carpetas sean correctas en rsvars .bat si tiene el compilador 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.

Nashev
fuente
Esa respuesta no está relacionada con Delphi y no es más robusta para los usuarios de Delphi.
Nashev
2
Perdón por ser conciso. Quise decir más robusto como en, funciona para algo más que Delphi. Puede haber una manera más fácil de hacerlo en Delphi, pero el OP no preguntó por Delphi, y este hilo tiene unas 18 respuestas que pocos verán. Si es importante para usted que otros lo vean, le recomiendo que cree una nueva pregunta específica para Delphi y responda a sí mismo. Si
obtuviéramos