2025-04-17 05:00:02

MSBuild路径

如何以编程方式从正在运行.exe的机器获取到MSBuild的路径?

我可以从环境中获得。net版本,但是是否有一种方法可以获得。net版本的正确文件夹?


当前回答

如果你想在。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

其他回答

对于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)。

获取最新版本的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;
}

这个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
}

这适用于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命令从注册表中获取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