MSBuild的路径

217

我如何在我的程序运行的机器上编写代码以获取MSBuild路径?

我可以从环境中获取 .NET 版本,但是否有一种方法可以获取特定 .NET 版本的正确文件夹路径?

23个回答

161

查看注册表,看起来像是

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\

7
我已安装了Visual Studio 2017 RC并启动开发人员命令提示符,MSBuild版本为15.+,但该版本未显示在注册表中。如何获取与Dev Cmd提示符使用的相同的MSBuild? - SuperJMN
6
MSBuild 15位于C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64\ - nZeus
2
只有在您安装了VS2017之后,我才能在注册表中找到15.0工具集的MsBuildToolsPath单个入口点。 - Paciv
14
MSBuild现在安装在每个Visual Studio版本的文件夹下。例如:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild。 同时,“ToolsVersion”值不再设置在注册表中。 - Hulvej
3
微软在GitHub上提供了一个项目(vswhere),用于确定Visual Studio 2017/msbuild 15.x的路径。这是一个单个可执行文件,可供您的构建软件/脚本使用。 - Roi Danton
显示剩余3条评论

146

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

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

2
请注意,如果您想构建 Windows Phone 应用程序,则需要使用 32 位的 msbuild。在 64 位机器上查询注册表仅会显示 64 位的 msbuild。 - Victor Ionescu
3
您可以在任何位数的cmd(或其他您正在运行的进程)上使用/reg:32/reg:64来明确获取该路径。 - Simon Buchan
这将为您提供到旧(4.0)位置的路径 - 您可能实际上想要的是其他地方,请参见https://dev59.com/clwY5IYBdhLWcg3w9r3a - JonnyRaa
在我的情况下,它位于 Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath 下。 - Sen Jacob

84

查找 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

(请注意,上述说明已经稍作修改,以适应您的使用情况。特别是,我包括了 -prerelease 标志以允许选择预览版和 RC 版本安装,并且 -products * 用于检测 Visual Studio Build Tools 安装。根据您的需要进行配置。)


经过两年多的等待,终于在2019年,微软倾听了我们的心声,并提供了一种查找这些重要可执行文件的方法!如果您已安装Visual Studio 2017或更新版本,则可以查询vswhere实用程序以获取MSBuild等的位置。由于vswhere保证位于%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe,因此不再需要引导、路径硬编码和注册表探测。

魔法在于-find参数, 添加于版本2.6.2。您可以通过运行vswhere或检查其文件属性来确定安装的版本。如果您有旧版本,您可以简单地下载最新版本并覆盖现有的%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe

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

如果您已安装Chocolatey您也可以使用相关的vswhere软件包


已经有3个答案提到了vswhere,其中包括您在其中一个答案下的评论。添加这个答案只会让答案变得更糟。 - jpaugh
10
我觉得这个答案很有用,而其他的vswhere答案则没能帮到我。 - cowlinator
1
值得注意的是,即使VSWHERE说这是要使用的msbuild.exe,也并不意味着如果您在命令行上键入msbuild(特别是在使用Visual Studio命令行时),就会使用该文件。要查看在命令行上键入msbuild时使用的是哪个文件,请执行以下操作:输入where msbuild。如果报告的内容与VSWHERE所说的最新和最好的版本不同,则必须指定要使用的msbuild.exe的完整路径或调整PATH变量以适应需求。 - Jinlye
1
那么接下来的问题是,你如何找到 vswhere 的路径... - BJury
1
@BJury 微软保证它始终位于“C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe”。那是你的起点。另外,如最后两段所述,您可以下载“vswhere.exe”并直接使用它。 - Ian Kemp
显示剩余2条评论

37

如果要使用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
适用于 $dotNetVersion 12.0 (vs 2013) 和 14.0 (vs 2015)(如果已安装)的工作。 - Julian
4
不适用于VS 2017,因为在 HKLM:\software\Microsoft\MSBuild\ToolsVersions 键下不添加任何值。相反,您需要从 HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStud‌​io\SxS\VS7\15.0 获取VS2017安装目录,然后附加 MSBuild\15.0\Bin\MSBuild.exe以获取MSBuild EXE位置。 - Ian Kemp

31

在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
@Elisée抱歉,那是复制/粘贴的打字错误。在我的环境中,我称变量为bb.build.msbuild.exe,当我将其粘贴到答案中时,我忽略了修复该实例。现在已经修复了,感谢你指出这一点。 - yoyo

30

您可以使用此试用版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

2
这个话题的最佳答案。 - Teoman shipahi
1
不幸的是,这已经不再是最佳选择,因为新版本是在VisualStudio中提供的,而不是在此处注册。 - Dmitry Gusarov
@hdev 感谢您的答案。如果有人正在寻找与Visual Studio一起使用的MSBuild.exe - 这适用于VS2019和VS2022PowerShell(来自文件系统) Resolve-Path 'C:\Program Files*\Microsoft Visual Studio\*\Professional\Msbuild\Current\bin\MSBuild.exe' - Sir CodesALot

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,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

2
注意:由于VS2017/msbuild 15.x不再使用注册表来存储路径,vswhere是确定msbuild路径的替代方案。 - Roi Danton
1
此外,AzizAtif是一个牛人。看看这个15.1版本构建 - https://github.com/linqpadless/LinqPadless/blob/master/build.cmd - JJS
2
此外,vswhere也可以通过Chocolatey安装:https://chocolatey.org/packages/vswhere - cowlinator

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

}

4
对于VS2017,请参见以下链接:https://github.com/Microsoft/vswhere,https://github.com/Microsoft/vssetup.powershell和https://github.com/deadlydog/Invoke-MsBuild。 - Ian Kemp
3
使用“vswhere -products *”作为构建工具,如https://github.com/Microsoft/vswhere/wiki/Find-MSBuild中所指定的那样。 - TN.
1
对于 vswhere,您应该知道它所在的路径。当然,您的构建系统应该有可用的 PowerShell。只有一个问题:为什么是 amd64?它是否有任何特定的构建内容? - Maxim
因为这个解决方案本质上只是使用了一个注册表键来支持MSBuild 15,而不是第三方库或脚本,所以我点了赞。出于好奇,“SxS \ VS7”是什么意思?它会在不同版本的VS中保持有效吗? - Lazlo

7

基于@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 - Ray Depew

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)中。 - Sascha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接