如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?
我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?
如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?
我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?
当前回答
在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安装文件夹中。
其他回答
在没有其他工具的情况下,从注册表中批量检索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(使用硬编码路径,如上面的代码片段)。 使用Microsoft.VisualStudio.Workload.MSBuildTools安装VisualStudio PowerShell模块
@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
有很多正确答案。然而,这里是我在PowerShell中使用的一行程序来确定最新版本的MSBuild路径:
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\' |
Get-ItemProperty -Name MSBuildToolsPath |
Sort-Object PSChildName |
Select-Object -ExpandProperty MSBuildToolsPath -first 1
您可能认为这里没有太多需要添加的内容,但也许现在是时候在所有版本中使用统一的方式来执行此操作了。我将注册表查询方法(VS2015及以下)与vwhere (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
}
查找MSBuild的说明:
PowerShell: &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * - required Microsoft. component .MSBuild -find MSBuild\**\Bin\MSBuild.exe CMD: "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -pre - release -products * - required Microsoft. component .MSBuild -find MSBuild\**\Bin\MSBuild.exe
查找VSTest的说明:
PowerShell: &"${env:ProgramFiles(x86)}\Microsoft VisualStudio \Installer\ vvswhere .exe" -latest -pre - release -products * -需要Microsoft. visualstudio . packagegroup . testtools . core -查找Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe CMD: "%ProgramFiles(x86)%\Microsoft VisualStudio \Installer\ vvswhere .exe" -latest -pre - release -products * - required Microsoft. visualstudio . packagegroup . testtools . core -find Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe
(请注意,上面的说明与微软的官方说明略有不同。特别地,我已经包含了-pre - release标志来允许预览和RC安装,以及-products *来检测Visual Studio Build Tools安装。)
这只花了两年多的时间,但最终在2019年,微软听取了我们的意见,并为我们提供了一种找到这些重要可执行文件的方法!如果你安装了Visual Studio 2017和/或2019,vwhere实用程序可以查询MSBuild等的位置。由于vswhere被Microsoft保证位于%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe,因此不再需要引导和路径硬编码。
神奇的是-find形参,它是在2.6.2版本中添加的。您可以通过运行vwhere或检查其文件属性来确定已安装的版本。如果您有较旧的版本,您可以下载最新的版本并覆盖现有的%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe。
Vswhere.exe是一个独立的可执行文件,因此您可以从任何有互联网连接的地方下载并运行它。这意味着您的构建脚本可以检查它们所运行的环境是否设置正确(举个例子)。
如果你已经安装了Chocolatey,你也可以使用相关的vwhere包。