我正在将我的.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"
任何指示?
答案 0 :(得分: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')
该方法基于this answer,并且已经推广并适用于PowerShell。
它基于由Visual Studio安装程序创建的系统环境变量VS*COMNTOOLS
,其中*
表示VS版本号(例如,VS 2010的100
)。< / p>
Sort-Object
用于确保最新的 Visual Studio安装是针对性的,如果多个并排安装:
$_.Name -replace '[^\d]'
中提取嵌入的版本号;例如,从100
中提取VS100COMNTOOLS
并将结果转换为整数({ {1}}); [int]
然后从排序数组中提取最后一个元素 - 即名称具有最高嵌入版本号的变量对象 - 并访问其值([-1]
)。 .Value
所在的IDE
子文件夹是MSTest.exe
指向的工具文件夹的 sibling 文件夹。
如果VS*COMNTOOLS
不在预期位置,MSTest.exe
默认会抛出非终止错误;添加Convert-Path
(简称:-EA Stop
)可确保脚本中止。
[1]
- 我已经尝试过Visual Studio 2015;请告诉我它是否适用于更高版本
- 可能也适用于VS 2008。
答案 1 :(得分: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
答案 2 :(得分: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;
}
答案 3 :(得分:-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]
}