如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?
我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?
如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?
我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?
当前回答
这个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
}
其他回答
您可能认为这里没有太多需要添加的内容,但也许现在是时候在所有版本中使用统一的方式来执行此操作了。我将注册表查询方法(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.exe的路径打印到命令行:
reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath
如果你想编译一个Delphi项目,请在使用msbuild+Delphi2009时查看“ERROR MSB4040 There is no target in the project”
正确答案是:“有一个批处理文件称为rsvars.bat(在RAD Studio文件夹中搜索它)。在调用MSBuild之前调用它,它将设置必要的环境变量。如果编译器的位置与默认位置不同,请确保rsvars.bat中的文件夹是正确的。”
这个bat不仅会将PATH环境变量更新到正确的。net文件夹,并使用正确的MSBuild.exe版本,还会注册其他必要的变量。
本处地点
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\2.0
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\3.5
给出可执行文件的位置。
但如果你需要保存任务扩展的位置,它是打开的
%ProgramFiles%\MSBuild
如果你有冒险精神,你也可以在https://github.com/Microsoft/msbuild/releases/上从GitHub获得源代码和MsBuild的最新版本