使用 powershell 找到 MSTest.exe

Locate MSTest.exe using powershell

我正在自动化我的 .Net 解决方案构建,以完全在 PowerShell 中构建。我想使用 PowerShell 定位 MSTest.exe。

我使用了下面的脚本来定位MSBuild.exe,我希望我能有类似的东西来定位MSTest.exe

$msBuildQueryResult = reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions.0" /v MSBuildToolsPath
$msBuildQueryResult = $msBuildQueryResult[2]
$msBuildQueryResult = $msBuildQueryResult.Split(" ")
$msBuildLocation = $msBuildQueryResult[12] + "MSBuild.exe"

有什么方向吗?

也许你想要这样的东西?

$regPath = "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions.0"
$regValueName = "MSBuildToolsPath"
$msBuildFilename = "MSBUild.exe"
if ( Test-Path $regPath ) {
  $toolsPath = (Get-ItemProperty $regPath).$regValueName
  if ( $toolsPath ) {
    $msBuild = Join-Path $toolsPath $msBuildFilename
    if ( -not (Test-Path $msBuild -PathType Leaf) ) {
      Write-Error "File not found - '$msBuild'"
    }
  }
}
# Full path and filename of MSBuild.exe in $msBuild variable

谢谢@Bill_Stewart,我用你的评论写了这个工作函数:

function Get-MSTest-Location {
    $msTests = @()
    $searchResults = Get-ChildItem C:\* -Filter MSTest.exe -Recurse -ErrorAction Ignore
    foreach($searchResult in $searchResults) {
        try{ 
            if(($searchResult.VersionInfo -ne $null) -and ($searchResult.VersionInfo.FileDescription -eq "Test Execution Command Line Tool"))
            { $msTests = $msTests + $searchResult.FullName }
        }
        catch{}
        }
    if($msTests.Length -eq 0)
    {return "MSTest not found."}
    return $msTests[0]
}

以下适用于 Visual Studio 2010 及更高版本[1]:

# Get the tools folder location:

# Option A: Target the *highest version installed*:
$vsToolsDir = (
  Get-Item env:VS*COMNTOOLS | Sort-Object {[int]($_.Name -replace '[^\d]')}
)[-1].Value

# Option B: Target a *specific version*; e.g., Visual Studio 2010,
# internally known as version 10.0.
# (See https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History)
$vsToolsDir = $env:VS100COMNTOOLS

# Now locate msbuild.exe in the "IDE" sibling folder.
$msTestExe = Convert-Path -EA Stop (Join-Path $vsToolsDir '..\IDE\MSTest.exe')

该方法基于 this answer 并被推广并适用于 PowerShell。

  • 基于系统环境变量VS*COMNTOOLS,由Visual Studio setup创建,其中*代表VS版本号(如100 VS 2010).

    • Re选项A:Sort-Object用于确保最近的 Visual Studio安装是有针对性的,应该并排安装多个:
      • 用于排序的脚本块首先仅从变量名中提取嵌入式版本号($_.Name -replace '[^\d]';例如,100 来自 VS100COMNTOOLS)并将结果转换为整数([int]); [-1] 然后从排序数组中提取最后一个元素 - 即名称具有最高嵌入版本号的变量对象 - 并访问它的值 (.Value).
  • MSTest.exe所在的IDE子文件夹是[=11=的tools文件夹的sibling文件夹]指向.

  • 如果MSTest.exe不在预期的位置,Convert-Path默认会抛出一个非终止错误;添加 -EA Stop-ErrorAction Stop 的缩写)可确保脚本 中止


[1]
- 我试过 Visual Studio 2015 年;让我知道它是否适用于更高版本。
- 可能也适用于 VS 2008。


我获取mstest路径的方式。 GetMSTestPath 函数是您调用的主要函数,如果第一个 GetMsTestPathFromVswhere 函数将找到它 returns 路径,否则您将进行长时间搜索 mstest.exe。通常,大约需要 10 秒。我知道这不是最好的,但至少当你努力寻找 mstest.exe 时它是有用的。希望它会对某人有所帮助。 :)))

 function GetMSTestPath
    {
        function GetTime()
        {
            $time_now = Get-Date -format "HH:mm:ss"
            return $time_now;
        }
        function GetMsTestPathFromVswhere {
            $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
            $path = & $vswhere -latest -prerelease -products * -requires Microsoft.Component.MSBuild -property installationPath
            #write-host $path
            if ($path) {
                $tool = join-path $path 'Common7\IDE\MSTest.exe'
                if (test-path $tool) {
                    return $tool
                }
                return ""
            }
        }

        function SeachForMsTestPath
        {

            write-host $(GetTime)
            $path =  Get-ChildItem C:\ -Filter MSTest.exe -Recurse -ErrorAction Ignore | ? { $_.VersionInfo.FileDescription -eq 'Test Execution Command Line Tool' } | Select -First 1
            write-host $(GetTime)
            return $path
        }

        $msTestExePath = GetMsTestPathFromVswhere
        if ([string]::IsNullOrEmpty($msTestExePath))
        {
            $msTestExePath = SeachForMsTestPath;
            if ([string]::IsNullOrEmpty($msTestExePath))
            {
                Write-host "MsTest path is not found. Exiting with error"
                Exit -1
            }
        }
        return $msTestExePath;
    }