Путь к MSBuild


186

Как программно получить путь к MSBuild с компьютера, на котором запущен мой .exe?

Я могу получить версию .NET из среды, но есть ли способ получить правильную папку для версии .NET?

Ответы:


141

Ковыряясь в реестре, похоже

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

может быть то, что вы после; запустите regedit.exe и посмотрите.

Запрос через командную строку (по Николаю Ботеву )

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

Запрос через PowerShell (за MovGP0 )

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

5
Я установил Visual Studio 2017 RC и запустил командную строку разработчика, версия MSBuild - 15. +, но эта версия не отображается в реестре. Как получить доступ к той же MSBuild, что и в Dev Cmd Prompt?
SuperJMN

6
MSBuild 15 находится по адресу `C: \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ amd64`
nZeus

2
Только если вы установили VS2017 там, я не смог найти ни одной точки входа в реестре для MsBuildToolsPath для набора инструментов 15.0
Paciv

8
docs.microsoft.com/en-us/visualstudio/msbuild/… "MSBuild теперь установлен в папке под каждой версией Visual Studio. Например, C: \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild "и" Значения ToolsVersion больше не устанавливаются в реестре "
Hulvej

2
@ORMapper Microsoft предлагает проект на GitHub для определения путей экземпляров Visual Studio 2017 / msbuild 15.x. Это один исполняемый файл, который может использоваться вашим программным обеспечением / скриптами для сборки.
Рой Дантон

140

Вы также можете распечатать путь MSBuild.exe в командной строке:

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

1
Обратите внимание, что если вы хотите создать приложение для Windows Phone, для этого требуется 32-битная версия msbuild. Запрос к реестру дает только 64-битную версию msbuild на 64-битной машине.
Виктор Ионеску

2
@VictorIonescu: Вы можете использовать /reg:32или /reg:64обе эти функции cmd(или любой процесс, который вы выполняете), чтобы явно получить этот путь.
Саймон Бьюкен

это даст вам путь к старому (4.0) местоположению - то, что вы, вероятно, хотите, действительно находится в другом месте, см. stackoverflow.com/questions/32007871/…
JonnyRaa

В моем случае это было подComputer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath
Сен Джейкоб

32

Если вы хотите использовать MSBuild для .Net 4, вы можете использовать следующую команду PowerShell, чтобы получить путь к исполняемому файлу. Если вы хотите версию 2.0 или 3.5, просто измените переменную $ dotNetVersion.

Для запуска исполняемого файла вам необходимо добавить переменную $ msbuild с &. Это будет выполнять переменную.

# 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

2
работает также для $dotNetVersion12.0 (против 2013) и 14.0 (против 2015) (если установлено, конечно)
Julian

4
Не работает для VS 2017, который не добавляет значение под HKLM:\software\Microsoft\MSBuild\ToolsVersionsключ. Вместо этого вам нужно получить установочный каталог VS2017 HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStud‌​io\SxS\VS7\15.0, а затем добавить, MSBuild\15.0\Bin\MSBuild.exeчтобы получить расположение MSBuild EXE.
Ян Кемп

30

Для сценариев оболочки cmd в Windows 7 я использую следующий фрагмент в моем пакетном файле, чтобы найти MSBuild.exe в .NET Framework версии 4. Я предполагаю, что версия 4 присутствует, но не принимаю подверсию. Это не совсем общее назначение, но для быстрых сценариев это может быть полезно:

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

Для моего использования я выхожу из командного файла с ошибкой, если это не сработало:

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 Зачем set bb.build.msbuild.exe=? Это требуется или просто артефакт вашей установки?
Елисей

@ Elisée Ой, простите, это опечатка. В моем окружении я вызываю переменную bb.build.msbuild.exe, я не стал исправлять этот экземпляр, когда вставлял в ответ. Исправлено сейчас, спасибо за указание на это.
йойо

26

Вы можете использовать эту пробную Команду PowerShell, чтобы получить MSBuildToolsPathиз реестра.

PowerShell (из реестра)

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

Вывод

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

или из файловой системы

PowerShell (из файловой системы)

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

Вывод

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

1
Лучший ответ на эту тему.
Теоман Шипахи

21

Инструкция по поиску 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

Инструкция по поиску 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

(Обратите внимание, что приведенные выше инструкции немного изменены по сравнению с официальными инструкциями Microsoft. В частности, я включил -prereleaseфлаг, позволяющий выбирать установки Preview и RC, а также -products *обнаруживать установки Visual Studio Build Tools.)


Это заняло всего два года, но, наконец, в 2019 году Microsoft прослушала и дала нам возможность найти эти важные исполняемые файлы ! Если у вас установлена ​​Visual Studio 2017 и / или 2019, vswhereутилиту можно запросить для определения местоположения MSBuild et al. Поскольку vswhere он всегда находится по адресу %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe , он не требует начальной загрузки и не требует жесткого кодирования пути.

Волшебство - это -findпараметр, добавленный в версии 2.6.2 . Вы можете определить версию, которую вы установили, запустив vswhereили проверив его свойства файла. Если у вас более старая версия, вы можете просто загрузить последнюю и перезаписать существующую %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe.

vswhere.exeЭто автономный исполняемый файл, поэтому вы можете скачать и запустить его из любого места, где есть подключение к Интернету. Это означает, что ваши сценарии сборки могут проверить, правильно ли настроена среда, в которой они работают, чтобы назвать одну опцию.


Уже есть 3 ответа, в которых упоминается vswhere, включая ваш комментарий на этот счет под одним из них. Добавление этого ответа только ухудшает ответ.
jpaugh

4
4 сейчас. Я нашел этот ответ полезным, в то время как другие ответы здесь не были полезными.
Cowlinator

Стоит отметить, что только потому, что VSWHERE говорит, что нужно использовать msbuild.exe, это не означает, что если вы наберете msbuildв командной строке (особенно в командной строке Visual Studio, если она используется), то это тот, который будет использоваться. Для того, чтобы увидеть , что привыкает , если вы вводите msbuildв командной строке, сделайте следующее: where msbuild. Если это не сообщает то же самое, что VSWHERE говорит, что последний и самый лучший из них, то либо вы должны указать полный путь к тому, который msbuild.exeвы хотите использовать, либо внести изменения в переменные PATH в соответствии с вашими потребностями.
Джинли

Итак, следующий вопрос: как найти путь туда, куда ...
BJury

17

@AllenSanborn имеет отличную версию PowerShell, но у некоторых есть требование использовать только сборочные сценарии для сборок.

Это прикладная версия ответа @ 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

Для Visual Studio 2017 / MSBuild 15 Азиз Атиф (парень, который написал Элму ) написал пакетный скрипт

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

2
Примечание. Поскольку VS2017 / msbuild 15.x не использует реестр для своих путей, vswhere является альтернативой для определения пути msbuild.
Рой Дантон

1
Также АзизАтиф это мужчина. Взгляните на это для сборки 15.1 - github.com/linqpadless/LinqPadless/blob/master/build.cmd
JJS

2
Также vswhere можно установить через Chocolatey: chocolatey.org/packages/vswhere
cowlinator

6

Это работает для Visual Studio 2015 и 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

}


3
Для Инструментов сборки используйте vswhere -products *, как указано в github.com/Microsoft/vswhere/wiki/Find-MSBuild .
TN.

Где вы должны знать путь, где он находится. И, конечно, вы должны иметь Power-Shell для вашей системы сборки. Только один вопрос: почему amd64? Есть ли что-то конкретное для строительства?
Максим

Проголосовал, потому что это решение по существу просто использует раздел реестра для MSBuild 15, а не стороннюю библиотеку или скрипт. Из любопытства, что означает "SxS \ VS7"? Это останется действительным через версии VS?
Лазло

5

Расположение реестра

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

укажите место для исполняемого файла.

Но если вам нужно место, где сохранить расширения задач, он включен

%ProgramFiles%\MSBuild

4
Я знаю, что он довольно старый, но в любом случае: на x64-системах папка MSBuild находится в ProgramFiles (x86)
Саша

4

Самый простой способ - открыть PowerShell и ввести

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

4

Однострочник, основанный на ответе @ dh_cgn :

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

Он выбирает все существующие пути, например. C:\Program Files (x86)\Microsoft Visual Studio\*\*\MSBuild\*\bin\msbuild.exe,

Звезды подстановочных знаков:

  • год (2017)
  • Visual Studio Edition (сообщество, профессионал, предприятие)
  • версия инструментов (15.0)

Помните, что эта команда выбирает первый путь, который соответствует выражению, упорядоченному по алфавиту. Чтобы сузить его, просто замените шаблоны с конкретными элементами, например. год или версия инструмента.


3

В Windows 2003 и более поздних версиях введите эту команду в cmd:

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

Если ничего не появляется, это означает, что .NET Framework не включен в системный PATH. MSBuild должен находиться в папке установки .NET вместе с компиляторами .NET (vbc.exe, csc.exe)


Этот ответ не добавляет много по сравнению с другими ответами. Это менее
надежно,

3

Начиная с MSBuild 2017 (v15), MSBuild теперь устанавливается в папке в каждой версии Visual Studio

Вот несколько примеров, где MSBuild.exe находится на моей машине:

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)

В соответствии с предыдущим ответом , 2017 делает фактически хранить эту информацию в реестре.
jpaugh

2

Чтобы получить путь к msbuild 15 (Visual Studio 2017) с пакетом из реестра без дополнительных инструментов:

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

Лучше доступные инструменты:


1
ты спас мне жизнь
Hakan Fıstık

Уже есть версия PowerShell этого. Около 2017 года, есть ли причина избегать изучения Powershell?
jpaugh

2
@jpaugh Не каждая система сборки имеет PowerShell.
Рой Дантон

1

Вы не думаете, что здесь есть что добавить, но, возможно, пришло время для единого способа сделать это во всех версиях. Я объединил подход с запросом реестра (VS2015 и ниже) с использованием vswhere (VS2017 и выше), чтобы придумать это:

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
}

1

Есть много правильных ответов. Тем не менее, здесь используется One-Liner в PowerShell, который используется для определения пути MSBuild для самой последней версии :

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\' | 
    Get-ItemProperty -Name MSBuildToolsPath | 
    Sort-Object PSChildName | 
    Select-Object -ExpandProperty MSBuildToolsPath -first 1

+1 Действительно полезно! Но в своем ответе я использую -last 1(вместо -first 1того, чтобы получить последнюю версию), а также объединяю имя файла (чтобы правильно получить полный путь, а не только папку).
Мариано Дезанце

1

Этот метод powershell получает путь к msBuild из нескольких источников. Пытаюсь по порядку:

  1. Сначала используйте vswhere (потому что Visual Studio, кажется, имеет более свежие версии msBuild), например

    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe
  2. Если не найдено, попробуйте реестр (версия фреймворка), например

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

Код 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
}

0

Для Visual Studio 2017, не зная точного издания, вы можете использовать это в пакетном скрипте:

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

Команда findstr игнорирует некоторые исполняемые файлы msbuild (в данном примере amd64).


0

добавьте ветку vswhere для https://github.com/linqpadless/LinqPadless/blob/master/build.cmd , отлично работает на моем компьютере, а ветка vswhere работает на компьютере моего помощника. Может быть, ветвь vswhere должна двигаться вперед как первая проверка.

@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


0

Получить последнюю версию MsBuild. Лучший способ для всех типов установки msbuild для разных процессорных архитектур (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;
}

-2

Если вы хотите скомпилировать проект Delphi, посмотрите на «ОШИБКА MSB4040 Нет цели в проекте» при использовании msbuild + Delphi2009

Правильный ответ там сказал: «Есть пакетный файл с именем rsvars.bat (найдите его в папке RAD Studio). Вызовите его перед вызовом MSBuild, и он установит необходимые переменные среды. Убедитесь, что в rsvars правильные папки .bat, если у вас есть компилятор в другом месте по умолчанию. "

Эта bat не только обновит переменную среды PATH до нужной папки .NET с правильной версией MSBuild.exe, но и зарегистрирует другие необходимые переменные.


Этот ответ не связан с Delphi и не является более надежным для пользователей Delphi.
Нашев

2
Извините за краткость. Я имел в виду более надежный, как работает, работает не только для Delphi. Возможно, есть более простой способ сделать это в Delphi, но ОП не спрашивал о Delphi, и в этой теме есть 18 ответов, которые мало кто когда-либо увидит. Если для вас важно, чтобы другие увидели это, я бы порекомендовал вам создать новый вопрос, специфичный для Delphi, и ответить на него самостоятельно. Если бы мы получили 6 или меньше ответов, охватывающих каждую версию MSBuild, я был бы очень счастлив
jpaugh
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.