MSBuild的路径


186

如何以编程方式从运行我的.exe的计算机上获取MSBuild的路径?

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

Answers:


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

通过命令行查询(根据Nikolay Botev

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. +,但是此版本未在注册表中显示。如何获得与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

8
docs.microsoft.com/zh-cn/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位计算机上的64位msbuild。
维克多·伊涅斯库

2
@VictorIonescu:您可以使用/reg:32/reg:64在两个bitnessess cmd(或任何处理您正在运行),明确获得该路径。
西蒙·布坎

这将为您提供通往旧(4.0)位置的路径-您可能想要的位置实际上是其他位置,请参见stackoverflow.com/questions/32007871/…–
JonnyRaa

在我的情况下,这是Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\MSBuild\ToolsVersions\4.0\MSBuildToolsPath
Sen Jacob

32

如果要使用MSBuild for .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(vs 2013)和14.0(vs 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

对于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éeOops,抱歉,这是复制/粘贴错字。在我的环境中,我将变量称为bb.build.msbuild.exe,但在粘贴到答案中时忽略了修复该实例。现在已修复,感谢您指出。
yoyo

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
关于此主题的最佳答案。
Teoman shipahi

19

查找MSBuild的说明

  • 电源外壳: &"${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的说明

  • 电源外壳: &"${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用于允许预览和RC安装以及-products *检测Visual Studio Build Tools安装的标志。)


仅用了两年时间,但终于在2019年,Microsoft倾听并给了我们找到这些重要可执行文件的方法!如果您已安装Visual Studio 2017和/或2019,则vswhere可以查询该实用程序以获取MSBuild等的位置。由于vswhere 始终位于 %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe,因此不再需要引导程序,也不需要进行路径硬编码。

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

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


已经有3个提到vswhere的答案,包括您对其中一个的评论。添加此答案只会使答案更糟。
jpaugh

4
现在4。我发现这个答案很有帮助,而其他vswhere答案却没有帮助。
cowlinator

值得一提的是,仅因为VSWHERE表示要使用的是msbuild.exe,但这并不意味着如果您msbuild在命令行中键入(尤其是在使用Visual Studio命令行的情况下),那将被使用。要查看msbuild在命令行输入时使用了什么,请执行以下操作:where msbuild。如果报告的结果与VSWHERE所说的最新和最大不一致,那么您要么必须为msbuild.exe要使用的对象提供完整路径,要么对PATH变量进行调整以适应需要。
Jinlye

所以下一个问题是如何找到通向vswhere的路径。...–
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,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路径的替代方法。
罗丹顿

1
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
对于Build Tools,请使用github.com/Microsoft/vswhere/wiki/Find-MSBuild中vswhere -products *指定的。
TN。

对于vswhere,您应该知道其位置。当然,您应该为构建系统提供Power-shell。只是一个问题:为什么选择amd64?它有什么特定的建筑吗?
Maxim

支持此提议,因为该解决方案实质上也只针对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-Folder位于ProgramFiles(x86)中
Sascha

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)
  • 视觉工作室版(社区,专业,企业)
  • 工具版本(15.0)

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


3

在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安装文件夹中。


这个答案与其他答案相比并没有多大好处。它的答案
jpaugh

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
您救了我的命
HakanFıstık18年

已经有一个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

有许多正确答案。但是,这里使用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

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


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项目,请在使用msbuild + Delphi2009时查看“错误MSB4040项目中没有目标”

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

该蝙蝠不仅会使用适当的MSBuild.exe版本将PATH环境变量更新为适当的.NET文件夹,还将注册其他必要的变量。


这个答案与Delphi无关,对于Delphi用户来说也没有那么强大。
纳许夫

2
很抱歉。我的意思是更强大,不仅适用于Delphi。在Delphi中可能有一种更简单的方法来执行此操作,但是OP并未询问有关Delphi的问题,并且该线程有18个答案,几乎没人会看到。如果对其他人来说这很重要,建议您创建一个特定于Delphi的新问题,并自行回答。如果我们能解决涵盖每个版本的MSBuild的6个或更少的答案,我会非常高兴
jpaugh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.