我如何以编程方式从运行.exe的机器获取MSBuild的路径?
我可以从环境中获取.NET版本但是有没有办法为.NET版本获取正确的文件夹?
您还可以将MSBuild.exe的路径打印到命令行:
reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath
看看注册表,它看起来像
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并查看.
reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath
dir HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\
如果要将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
对于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
您可以使用此试用版PowerShell命令MSBuildToolsPath
从注册表中获取.
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
@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
查找MSBuild的说明:
"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe
查找VSTest的说明:
"C:\Program Files (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
允许使用Preview和RC安装以及-products *
检测Visual Studio Build Tools安装的标记。)
仅用了两年时间,但终于在2019年,Microsoft倾听并给了我们找到这些重要可执行文件的方法!如果您已安装Visual Studio 2017和/或2019,则vswhere
可以查询该实用程序以获取MSBuild等的位置。由于vswhere
始终位于C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
,因此不再需要引导程序,也不需要进行路径硬编码。
魔法是在版本2.6.2中添加的-find
参数。您可以通过运行或检查其文件属性来确定已安装的版本。如果您使用的是旧版本,则只需下载一个新版本并覆盖现有版本即可。vswhere
C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
vswhere.exe
是一个独立的可执行文件,因此您可以从具有Internet连接的任何位置下载并运行它。这意味着您的构建脚本可以检查运行它们的环境是否正确设置(仅举一个选项)。
注册表位置
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\2.0 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\3.5
给出可执行文件的位置.
但是,如果您需要保存任务扩展的位置,它就会打开
%ProgramFiles%\MSBuild
这适用于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 }
最简单的方法可能是打开PowerShell并输入
dir HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\