如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?
我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?
如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?
我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?
当前回答
获取最新版本的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;
}
其他回答
从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)
如果你想在。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
为https://github.com/linqpadless/LinqPadless/blob/master/build.cmd添加vwhere分支,在我的计算机上运行良好,vwhere分支在我伴侣的计算机上运行良好。 也许,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
这个powershell方法从多个源获取msBuild的路径。按顺序尝试:
首先使用vwhere(因为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://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
}
如果你有冒险精神,你也可以在https://github.com/Microsoft/msbuild/releases/上从GitHub获得源代码和MsBuild的最新版本