Caminho para o MSBuild

186

Como posso programaticamente obter o caminho para o MSBuild de uma máquina em que meu .exe está sendo executado?

Posso obter a versão .NET do Environment, mas existe uma maneira de obter a pasta correta para uma versão .NET?

dagda1
fonte

Respostas:

141

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

pode ser o que você procura; inicie o regedit.exe e dê uma olhada.

Consulta via linha de comando (por Nikolay Botev )

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

Consulta via PowerShell (por MovGP0 )

dir HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\
Brian
fonte
5
Instalei o Visual Studio 2017 RC e inicie o Prompt de Comando do Desenvolvedor, a versão do MSBuild é 15. +, mas esta versão não aparece no registro. Como obtenho acesso ao mesmo MSBuild que o Prom Cmd Dev está usando?
precisa saber é o seguinte
6
O MSBuild 15 está localizado em `C: \ Arquivos de Programas (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ amd64`
nZeus
2
Somente se você instalou o VS2017 lá, não foi possível encontrar um único ponto de entrada no registro do MsBuildToolsPath para o conjunto de ferramentas 15.0
Paciv
8
docs.microsoft.com/en-us/visualstudio/msbuild/… "O MSBuild agora está instalado em uma pasta em cada versão do Visual Studio. Por exemplo, C: \ Arquivos de Programas (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild "e" ToolsVersion valores não estão mais definidos no registro "
Hulvej
2
O @ORMapper Microsoft oferece um projeto no GitHub para determinar os caminhos das instâncias do Visual Studio 2017 / msbuild 15.x. É um único executável que pode ser usado pelo seu software / script de construção.
Roi Danton
140

Você também pode imprimir o caminho do MSBuild.exe na linha de comando:

reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath
Nikolay Botev
fonte
1
Observe que, se você deseja criar um aplicativo para telefone com Windows, é necessário o msbuild de 32 bits. A consulta ao registro fornece apenas o msbuild de 64 bits em uma máquina de 64 bits.
Victor Ionescu
2
@ VictorIonescu: Você pode usar /reg:32ou /reg:64nas duas testemunhas cmd(ou em qualquer processo que esteja executando) para obter explicitamente esse caminho.
Simon Buchan
isso vai lhe dar o caminho para um velho (4.0) localização - o que você quer provavelmente está realmente em outro lugar ver stackoverflow.com/questions/32007871/...
JonnyRaa
No meu caso, estava sobComputer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath
Sen Jacob
32

Se você quiser usar o MSBuild for .Net 4, poderá usar o seguinte comando do PowerShell para obter o caminho do executável. Se você deseja a versão 2.0 ou 3.5, basta alterar a variável $ dotNetVersion.

Para executar o executável, você precisará acrescentar a variável $ msbuild com &. Isso executará a variável.

# 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
fonte
2
funciona também para $dotNetVersion12.0 (vs 2013) e 14.0 (vs 2015) (se instalado, é claro)
Julian
4
Não funciona para o VS 2017, que não adiciona um valor sob a HKLM:\software\Microsoft\MSBuild\ToolsVersionschave. Em vez disso, você precisa obter o dir de instalação do VS2017 HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStud‌​io\SxS\VS7\15.0e anexá MSBuild\15.0\Bin\MSBuild.exe-lo para obter o local do MSBuild EXE.
Ian Kemp
30

Para scripts de shell do cmd no Windows 7, eu uso o seguinte fragmento no meu arquivo em lotes para encontrar o MSBuild.exe no .NET Framework versão 4. Presumo que a versão 4 esteja presente, mas não assuma a sub-versão. Isso não é totalmente de uso geral, mas, para scripts rápidos, pode ser útil:

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

Para meus usos, estou saindo do arquivo em lotes com um erro se isso não funcionar:

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
yoyo
fonte
@yoyo Para que serve set bb.build.msbuild.exe=? É necessário ou apenas um artefato de sua configuração?
Elisée 17/05
@ Elisée Ops, desculpe, isso é um erro de copiar / colar. No meu ambiente, chamo a variável bb.build.msbuild.exe, esqueci de corrigir essa instância quando colei a resposta. Corrigido agora, obrigado por apontar isso.
yoyo 17/05
26

Você pode usar esse comando do PowerShell de avaliação para obter MSBuildToolsPatho registro.

PowerShell (do registro)

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

Resultado

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

ou do sistema de arquivos

PowerShell (do sistema de arquivos)

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

Resultado

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
fonte
1
A melhor resposta sobre este tópico.
Teoman shipahi
19

Instruções para encontrar o MSBuild :

  • PowerShell: &"${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

Instruções para encontrar o VSTest :

  • PowerShell: &"${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

(Observe que as instruções acima são ligeiramente modificadas das instruções oficiais da Microsoft. Em particular, incluí o -prereleasesinalizador para permitir que instalações de visualização e RC sejam selecionadas e -products *para detectar instalações das Ferramentas de compilação do Visual Studio.)


Demorou apenas dois anos, mas finalmente em 2019, a Microsoft ouviu e nos deu uma maneira de encontrar esses executáveis ​​vitais ! Se você possui o Visual Studio 2017 e / ou 2019 instalado, o vswhereutilitário pode ser consultado quanto à localização de MSBuild et al. Como vswhere sempre está localizado em %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe , não há mais bootstrapping nem caminho necessário para a codificação do caminho.

A mágica é o -findparâmetro, adicionado na versão 2.6.2 . Você pode determinar a versão que você instalou executando vswhereou verificando suas propriedades do arquivo. Se você possui uma versão mais antiga, basta baixar a mais recente e substituir a existente %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe.

vswhere.exeé um executável independente, para que você possa baixá-lo e executá-lo de qualquer lugar com uma conexão à Internet. Isso significa que seus scripts de construção podem verificar se o ambiente em que estão executando está configurado corretamente, para citar uma opção.

Ian Kemp
fonte
Já existem três respostas que mencionam vswhere, incluindo seu comentário nesse sentido em uma delas. Adicionar esta resposta apenas piora a sopa de respostas.
jpaugh
4
4 agora. Achei esta resposta útil, enquanto não achei as outras respostas vswhere úteis.
cowlinator
Vale ressaltar que, apenas porque o VSWHERE diz que é o msbuild.exe a ser usado, isso não significa que, se você digitar msbuildna linha de comando (especialmente a linha de comando do Visual Studio, se estiver usando isso), essa será a que será usada. Para ver o que é usado se você digitar msbuildna linha de comando, faça o seguinte: where msbuild. Se isso não está relatando o mesmo que o VSWHERE diz que o mais recente e o melhor é, então você precisa fazer um caminho completo para o msbuild.exeque deseja usar ou fazer ajustes nas variáveis ​​PATH para adequá-lo.
Jinlye 11/07/19
Portanto, a próxima questão é como você encontrar o caminho para vswhere ....
BJury
17

O @AllenSanborn possui uma excelente versão do PowerShell, mas algumas pessoas precisam usar apenas scripts em lote para compilações.

Esta é uma versão aplicada do que o @ bono8106 respondeu.

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

No Visual Studio 2017 / MSBuild 15, Aziz Atif (o cara que escreveu Elmah ) escreveu um script em lote

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
fonte
2
Nota: Como o VS2017 / msbuild 15.x não usa o registro para seus caminhos, vswhere é uma alternativa para determinar o caminho do msbuild.
Roi Danton
1
Além disso, AzizAtif é o homem. Dê uma olhada nisso para compilações 15.1 - github.com/linqpadless/LinqPadless/blob/master/build.cmd
JJS
2
Além disso, vswhere pode ser instalado via Chocolatey: chocolatey.org/packages/vswhere
cowlinator
6

Isso funciona para o Visual Studio 2015 e 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
fonte
3
Para Ferramentas de compilação, use vswhere -products *, conforme especificado em github.com/Microsoft/vswhere/wiki/Find-MSBuild .
TN.
Para vswhere, você deve saber o caminho em que está localizado. E é claro que você deve ter o power-shell disponível para o seu sistema de compilação. Apenas uma pergunta: por que amd64? Tem algo específico para a construção?
Maxim
Promovido porque esta solução também usa essencialmente uma chave de registro para o MSBuild 15, não uma biblioteca ou script de terceiros. Por curiosidade, a que "SxS \ VS7" se refere? Isso permanecerá válido nas versões do VS?
Lazlo
5

Os locais do registro

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

forneça o local para o executável.

Mas se você precisar do local onde salvar as extensões de tarefas, ele estará ativado

%ProgramFiles%\MSBuild
Paulo Santos
fonte
4
É muito velho, eu sei - mas de qualquer maneira: em x64-Systems, o MSBuild-pasta está localizada na ProgramFiles (x86)
Sascha
4

A maneira mais fácil pode ser abrir o PowerShell e inserir

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

Um one-liner baseado na resposta de @ dh_cgn :

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

Ele seleciona todos os caminhos existentes, por exemplo. C:\Program Files (x86)\Microsoft Visual Studio\*\*\MSBuild\*\bin\msbuild.exe.

As estrelas curingas são:

  • o ano (2017)
  • a edição do visual studio (comunidade, profissional, empresa)
  • a versão das ferramentas (15.0)

Esteja ciente de que este comando está selecionando o primeiro caminho que corresponde à expressão ordenada por alfabeto. Para reduzi-lo, substitua os curingas por elementos específicos, por exemplo. o ano ou a versão das ferramentas.

SeriousM
fonte
3

No Windows 2003 e posterior, digite este comando no cmd:

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

Se nada aparecer, significa que o .NET framework não está incluído no PATH do sistema. O MSBuild deve estar na pasta de instalação do .NET, juntamente com os compiladores do .NET (vbc.exe, csc.exe)

draganicimw
fonte
Esta resposta não acrescenta muito sobre outras respostas. É menos robusto do que esta resposta
jpaugh
3

A partir do MSBuild 2017 (v15), o MSBuild agora está instalado em uma pasta em cada versão do Visual Studio

Aqui estão alguns exemplos de onde o MSBuild.exe é encontrado na minha 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
fonte
De acordo com a resposta anterior de 2017 faz na loja fato de esta informação no registro.
jpaugh
2

Para recuperar o caminho do msbuild 15 (Visual Studio 2017) com lote do registro sem ferramentas adicionais:

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

Melhores ferramentas disponíveis:

Roi Danton
fonte
1
você salvou minha vida
Hakan Fıstık
Já existe uma versão do PowerShell . Por volta de 2017, há alguma razão para evitar o aprendizado do PowerShell?
jpaugh
2
@jpaugh Nem todo sistema de compilação tem o PowerShell disponível.
Roi Danton
1

Você não acha que há muito a acrescentar aqui, mas talvez seja hora de uma maneira unificada de fazer isso em todas as versões. Combinei a abordagem de consulta de registro (VS2015 e abaixo) com o uso de vswhere (VS2017 e acima) para obter isso:

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

Existem muitas respostas corretas. No entanto, aqui um One-Liner no PowerShell que eu uso para determinar o caminho do MSBuild para a versão mais recente :

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\' | 
    Get-ItemProperty -Name MSBuildToolsPath | 
    Sort-Object PSChildName | 
    Select-Object -ExpandProperty MSBuildToolsPath -first 1
Martin Brandl
fonte
+1 realmente útil! Mas na minha resposta eu uso -last 1(em vez de -first 1obter a versão mais recente) e também concatenar o nome do arquivo (para obter corretamente o caminho completo e não apenas a pasta).
Mariano Desanze
1

Esse método do PowerShell obtém o caminho para o msBuild de várias fontes. Tentando em ordem:

  1. Primeiro usando vswhere (porque o Visual Studio parece ter versões mais atualizadas do msBuild), por exemplo

    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe
  2. Se não for encontrado, tente o registro (versão da estrutura), por exemplo

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

Código do 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
fonte
0

Para o Visual Studio 2017 sem saber a edição exata, você pode usá-lo em um script em lote:

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

O comando findstr é ignorar certos executáveis ​​do msbuild (neste exemplo, o amd64).

Ernstjan Freriks
fonte
0

adicione o ramo vswhere em https://github.com/linqpadless/LinqPadless/blob/master/build.cmd , funciona bem no meu computador e o ramo vswhere funciona no computador do meu companheiro. Pode ser que o ramo vswhere deva avançar como a primeira verificação.

@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
fonte
0

Obtenha a versão mais recente do MsBuild. A melhor maneira, para todos os tipos de instalação do msbuild, para diferentes arquiteturas de processador (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
fonte
-2

Se você deseja compilar um projeto Delphi, consulte "ERRO MSB4040 Não há destino no projeto" ao usar o msbuild + Delphi2009

A resposta correta é dita: "Existe um arquivo em lotes chamado rsvars.bat (procure-o na pasta RAD Studio). Chame isso antes de chamar o MSBuild e ele configurará as variáveis ​​de ambiente necessárias. Verifique se as pastas estão corretas no rsvars .bat se você tiver o compilador em um local diferente do padrão. "

Este bastão não apenas atualiza a variável de ambiente PATH para a pasta .NET apropriada com a versão apropriada do MSBuild.exe, mas também registra outras variáveis ​​necessárias.

Nashev
fonte
Essa resposta não é relacionada ao Delphi e não é mais robusta para os usuários do Delphi.
Nashev 22/11
2
Desculpe por ser conciso. Eu quis dizer mais robusto, trabalha para mais do que apenas o Delphi. Pode haver uma maneira mais fácil de fazer isso no Delphi, mas o OP não perguntou sobre o Delphi, e esse tópico tem cerca de 18 respostas que poucos verão. Se é importante para você que outras pessoas vejam isso, eu recomendo que você crie uma nova pergunta específica para o Delphi e responda a si mesma. Se chegamos até 6 ou menos respostas que cobriam todas as versões do MSBuild, eu ficaria muito feliz
jpaugh