Путь к MSBuild - PullRequest
       105

Путь к MSBuild

175 голосов
/ 30 ноября 2008

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

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

Ответы [ 20 ]

3 голосов
/ 01 ноября 2018

Однострочник на основе ответа @ 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 голосов
/ 18 августа 2017

Начиная с 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)
3 голосов
/ 09 сентября 2015

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

2 голосов
/ 22 декабря 2017

Чтобы получить путь 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

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

0 голосов
/ 18 апреля 2019

Если вы любите приключения, вы также можете получить исходный код и последнюю версию MsBuild от GitHub сейчас на https://github.com/Microsoft/msbuild/releases/

0 голосов
/ 22 января 2019

добавить ветку 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 голосов
/ 14 ноября 2018

Для 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 голосов
/ 05 июня 2019

Получить последнюю версию 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;
}
0 голосов
/ 06 июня 2019

Вы не думаете, что здесь есть что добавить, но, возможно, пришло время для единого способа сделать это во всех версиях. Я объединил подход запроса реестра (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
}
0 голосов
/ 15 июня 2017

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...