MSBuild 的路径

Posted

技术标签:

【中文标题】MSBuild 的路径【英文标题】:Path to MSBuild 【发布时间】:2010-09-24 14:08:15 【问题描述】:

如何以编程方式从运行 .exe 的机器获取 ?

我可以从环境中获取 .NET 版本,但有没有办法为 .NET 版本获取正确的文件夹?

【问题讨论】:

【参考方案1】:

Instructions for finding 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

Instructions for finding 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

(请注意,上面的说明与微软官方的说明略有修改。特别是,我包含了-prerelease 标志以允许选择预览和RC 安装,并包含-products * 以检测Visual Studio Build工具安装。)


只用了两年多,终于在2019年,Microsoft has listened and given us a way to find these vital executables!如果您安装了 Visual Studio 2017 和/或 2019,则可以在 vswhere 实用程序中查询 MSBuild 等的位置。由于vswhere Microsoft 保证位于 %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe,因此不再需要引导和路径硬编码。

神奇的是-find 参数added in version 2.6.2。您可以通过运行vswhere 或检查其文件属性来确定您安装的版本。如果您有旧版本,您可以简单地download the latest one 并覆盖现有的%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe

vswhere.exe 是一个独立的可执行文件,因此您可以从任何有互联网连接的地方下载并运行它。这意味着您的构建脚本可以检查它们运行的​​环境是否设置正确,仅举一个选项。

如果你安装了Chocolatey,you can also use the relevant vswhere package。

【讨论】:

已经有 3 个答案提到了 vswhere,包括您在其中一个下对此的评论。添加这个答案只会让答案变得更糟。 4 现在。我发现这个答案很有帮助,而我没有发现其他 vswhere 答案有帮助。 值得注意的是,仅仅因为 VSWHERE 说这是要使用的 msbuild.exe,并不意味着如果您在命令行中键入 msbuild(尤其是 Visual Studio 命令行,如果使用它) ,那是会被使用的。要查看在命令行中键入 msbuild 时使用的内容,请执行以下操作:where msbuild。如果报告的结果与 VSWHERE 所说的最新和最好的报告不同,那么您要么必须为要使用的 msbuild.exe 提供完整路径,要么对 PATH 变量进行调整以适应。 那么接下来的问题就是如何找到到vswhere的路径...... @BJury Microsoft 保证它将始终位于“C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe”。那是你的出发点。或者,如最后 2 段所述,您可以下载 vswhere.exe 并直接使用。【参考方案2】:

此 powershell 方法从多个来源获取 msBuild 的路径。按顺序尝试:

    首先使用 vswhere(因为 Visual Studio 似乎有更多最新版本的 msBuild)例如

    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe
    

    如果没有找到尝试注册表(框架版本),例如

    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://***.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

【讨论】:

【参考方案3】:

有很多正确的答案。但是,这里我使用 PowerShell 中的 One-Liner确定最新版本的 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 来获取最新版本)并连接文件名(以正确获取完整路径而不仅仅是文件夹)。【参考方案4】:

您不会认为这里有太多要添加的内容,但也许是时候采用一种统一的方式在所有版本中执行此操作了。我将注册表查询方法(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

【讨论】:

【参考方案5】:

获取最新版本的 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;

【讨论】:

【参考方案6】:

如果您喜欢冒险,您现在还可以从 GitHub 获取 MsBuild 的源代码和最新版本,地址为 https://github.com/Microsoft/msbuild/releases/

【讨论】:

不回答 OP 的任何一个问题【参考方案7】:

为https://github.com/linqpadless/LinqPadless/blob/master/build.cmd 添加vswhere 分支,在我的电脑上运行良好,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

【讨论】:

【参考方案8】:

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

【讨论】:

根据previous answer,2017 确实实际上将此信息存储在注册表中。【参考方案9】:

查看注册表,看起来像

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 并查看。

通过命令行查询(Nikolay Botev)

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

通过 PowerShell 查询(根据 MovGP0)

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

【讨论】:

我已安装 Visual Studio 2017 RC 并启动开发人员命令提示符,MSBuild 版本为 15.+,但此版本未显示在注册表中。如何访问 Dev Cmd Prompt 正在使用的同一个 MSBuild? MSBuild 15 位于 `C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64` 仅当您在那里安装了 VS2017 时,我无法在注册表中为 15.0 工具集的 MsBuildToolsPath 找到单个入口点 docs.microsoft.com/en-us/visualstudio/msbuild/… "MSBuild 现在安装在每个 Visual Studio 版本下的文件夹中。例如,C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild" 和 " ToolsVersion 值不再在注册表中设置" @O.R.Mapper Microsoft 提供a project on GitHub 用于确定 Visual Studio 2017/msbuild 15.x 实例的路径。它是一个可执行文件,可供您的构建软件/脚本使用。【参考方案10】:

基于@dh_cgn's answer的单行代码:

(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 版(社区、专业、企业) 工具版本 (15.0)

请注意,此命令选择与按字母排序的表达式匹配的第一个路径。要缩小范围,只需将通配符替换为特定元素,例如。年份或工具版本。

【讨论】:

添加 amd64 以查找 64 位的:``` (Resolve-Path ([io.path]::combine($env:ProgramFiles(x86), 'Microsoft Visual Studio', '', '', 'MSBuild', '*' , 'bin' , 'amd64', 'msbuild.exe')).Path ``【参考方案11】:

对于不知道确切版本的 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)。

【讨论】:

【参考方案12】:

@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,Aziz Atif(编写 Elmah 的人)编写了一个批处理脚本

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

【讨论】:

注意:由于 VS2017/msbuild 15.x 不使用注册表作为其路径,vswhere 是确定 msbuild 路径的替代方法。 另外,AzizAtif 就是这个人。看看这个 15.1 版本 - github.com/linqpadless/LinqPadless/blob/master/build.cmd 另外,vswhere 可以通过 Chocolatey 安装:chocolatey.org/packages/vswhere【参考方案13】:

您可以使用这个非常试用的 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

【讨论】:

这个话题的最佳答案。 不幸的是,这不再是最好的了,因为较新的版本是在 VisualStudio 中提供的,而不是在这里注册【参考方案14】:

要使用批处理从注册表中检索 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

更好的可用工具:

vswhere:找到 Visual Studio 2017 和更新的安装,请参阅 get msbuild15 path with batch(使用硬编码路径作为我上面的 sn-p)。 Visual Studio Setup PowerShell Module 使用 Microsoft.VisualStudio.Workload.MSBuildTools

【讨论】:

你救了我的命 已经有一个PowerShell 版本。大约 2017 年,有什么理由不学习 Powershell? @jpaugh 并非每个构建系统都有可用的 PowerShell。【参考方案15】:

如果你想编译一个Delphi项目,看"ERROR MSB4040 There is no target in the project" when using msbuild+Delphi2009

正确答案是:“有一个名为 rsvars.bat 的批处理文件(在 RAD Studio 文件夹中搜索它)。在调用 MSBuild 之前调用它,它将设置必要的环境变量。如果您的编译器与默认位置不同,请确保 rsvars.bat 中的文件夹正确无误。"

这个 bat 不仅会更新 PATH 环境变量到正确的 .NET 文件夹和正确的 MSBuild.exe 版本,还会注册其他必要的变量。

【讨论】:

这个答案与 Delphi 无关,对 Delphi 用户来说也不是更强大。 对不起,太简洁了。我的意思是更健壮,不仅仅适用于 Delphi。在 Delphi 中可能有一种更简单的方法,但 OP 没有询问 Delphi,并且这个线程有一些很少有人会看到的 18 个答案。如果其他人看到这一点对您很重要,我建议您创建一个特定于 Delphi 的新问题并自行回答。如果我们得到涵盖每个 MSBuild 版本的 6 个或更少的答案,我会非常高兴【参考方案16】:

这适用于 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


【讨论】:

对于 VS2017,另请参阅:github.com/Microsoft/vswhere、github.com/Microsoft/vssetup.powershell 和 github.com/deadlydog/Invoke-MsBuild 对于构建工具,使用vswhere -products *,如github.com/Microsoft/vswhere/wiki/Find-MSBuild 中指定的那样。 对于vswhere你应该知道它所在的路径。当然,您应该为您的构建系统提供 power-shell。只有一个问题:为什么是amd64?它有什么特定的建筑吗? 赞成,因为这个解决方案本质上也只是使用了 MSBuild 15 的注册表项,而不是第三方库或脚本。出于好奇,“SxS\VS7”指的是什么?这会在 VS 版本中保持有效吗?【参考方案17】:

对于 Windows 7 中的 cmd shell 脚本,我在批处理文件中使用以下片段在 .NET Framework 版本 4 中查找 MSBuild.exe。我假设版本 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,当我粘贴到答案中时,我忽略了修复该实例。现已修复,感谢您指出这一点。【参考方案18】:

在 Windows 2003 及更高版本上,在 cmd 中键入以下命令:

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

如果没有出现,则表示 .NET 框架未包含在系统 PATH 中。 MSBuild 应与 .NET 编译器(vbc.exe、csc.exe)一起位于 .NET 安装文件夹中

【讨论】:

这个答案与其他答案相比并没有增加太多。它不如 this answer 健壮【参考方案19】:

最简单的方法可能是打开 PowerShell 并输入

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

【讨论】:

【参考方案20】:

也可以将MSBuild.exe的路径打印到命令行:

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

【讨论】:

请注意,如果您想构建一个 windows phone 应用程序,则需要 32 位 msbuild。在 64 位机器上查询注册表只能得到 64 位 msbuild。 @VictorIonescu:您可以在cmd(或您正在运行的任何进程)的两个位上使用/reg:32/reg:64 来显式获取该路径。 这将为您提供通往旧 (4.0) 位置的路径 - 您可能想要的位置实际上在其他地方,请参阅 ***.com/questions/32007871/… 在我的情况下它在Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath【参考方案21】:

如果您想为 .Net 4 使用 MSBuild,那么您可以使用以下 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

【讨论】:

也适用于$dotNetVersion 12.0(与 2013 相比)和 14.0(与 2015 相比)(当然如果已安装) Does not work for VS 2017, which does not add a value under the HKLM:\software\Microsoft\MSBuild\ToolsVersions key. 相反,您需要从 HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStud‌​io\SxS\VS7\15.0 获取 VS2017 安装目录,然后附加 MSBuild\15.0\Bin\MSBuild.exe 以获取 MSBuild EXE 位置。【参考方案22】:

注册表位置

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

给出可执行文件的位置。

但如果你需要保存任务扩展的位置,它就在

%ProgramFiles%\MSBuild

【讨论】:

它已经很老了,我知道 - 但无论如何:在 x64-Systems 上,MSBuild-Folder 位于 ProgramFiles(x86) 中

以上是关于MSBuild 的路径的主要内容,如果未能解决你的问题,请参考以下文章

给定相对路径时,如何让 MSBUILD 评估和打印完整路径?

MSBuild 的路径

MSBuild 不解析路径内的参数

Docs-VisualStudio-MSBuild-MSBuild参考:常用的 MSBuild 项目项

使用 MSBuild 构建后运行测试时出现 MissingManifestResourceException(.mresource 在清单中有路径)

Ionic / Cordova Windows 构建拾取不正确的 MSBUILD 路径