2

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

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

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

有什么方向吗?

4

4 回答 4

2

以下适用于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')

该方法基于此答案,并已推广并适用于 PowerShell。

  • 它基于系统环境变量VS*COMNTOOLS,由 Visual Studio 安装程序创建,其中*表示 VS 版本号(例如,100对于 VS 2010)。

    • 重新选项 A:Sort-Object用于确保以最新的Visual Studio 安装为目标,如果并排安装多个:
      • 用于排序的脚本块首先从变量名($_.Name -replace '[^\d]'; 例如,100from VS100COMNTOOLS)中仅提取嵌入的版本号,并将结果转换为整数([int]);[-1]然后从排序后的数组中提取最后一个元素 - 即名称具有最高嵌入版本号的变量对象 - 并访问其值 ( .Value)。
  • IDE子文件夹所在的文件夹是所指向的工具文件夹MSTest.exe同级文件夹。VS*COMNTOOLS

  • 如果不在MSTest.exe预期位置,Convert-Path默认会抛出非终止错误;添加-EA Stop(简称-ErrorAction Stop:)确保脚本被中止


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


于 2016-02-10T23:14:06.923 回答
1

也许你想要这样的东西?

$regPath = "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.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
于 2016-02-09T21:06:57.680 回答
0

我获得 mstest 路径的方式。GetMSTestPath 函数是您调用的主函数,然后如果第一个 GetMsTestPathFromVswhere 函数会找到它返回路径的东西,如果不是,您将长时间搜索 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;
    }
于 2020-03-03T13:25:45.570 回答
-1

感谢@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]
}
于 2016-02-10T22:35:25.733 回答