使用 Powershell 自动化 VSPerfCmd.exe(Visual Studio 性能分析)
Using Powershell to Automate VSPerfCmd.exe (Visual Studio Performance Profiling)
因为这个问题是我尝试解决问题的尝试,所以我在下面的 post 中包含了重要的背景和调查历史。因此,我将 post 分为 3 个部分:"Background"、"Investigation So Far" 和 "Problem"。当我自己进行更多调查时,我还添加了一个 "Additional Investigation" 部分来扩展我的发现。这最终导致我自己解决了这个问题,并且我将原始的 post 作为任何尝试做同样事情的开发人员的指南。该问题最终成为 return 控制问题 VSPerfCmd.exe 在 v1.
之后的 Powershell 版本中出现
- Background
作为我的 TFS 构建(包括自动部署到我的开发 Web 服务器 DEV)的一部分,我想开始 运行 我的代码的性能测试,以便我可以看到什么时候有新的变化对我 API 的速度产生负面影响。为此,我在 DEV 上安装了 test-运行ner (SoapUI) 和 VS Team Tools,并编写了一个 Powershell 脚本,当 运行 local 在 DEV 上,生成我想要的报告。但是,我还无法触发该脚本并让它在任何其他位置运行。我的意思是说,只有登录到服务器,找到 .ps1 文件并在 Powershell 中 运行 将其 shell 才能工作。这是该脚本:
#script location+name \DEV\C$\PerformanceTest\profile-tracing-SoapUI.ps1
$startPath = Get-Location
$siteUrl = "http://api.dev.com"
$sleepTime = 5
$logLocation = "C:\reports\api"
$websiteLocation = "W:\Sites\API\Code\API\_PublishedWebsites\API\bin"
try
{
#Instrument the API dlls
Write-Host "Instrumenting DLLs..."
Get-ChildItem $websiteLocation "API*.dll" | ForEach-Object {
Set-Location -Path $websiteLocation
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSInstr.exe" $_.Name
}
#set location back to start
Set-Location -Path $startPath
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCLREnv.cmd" /GlobalTraceOn
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCLREnv.cmd" /GlobalInteractionOn
#launch the profiler on the site
Write-Host "Starting the trace..."
#start:Trace - in tracing mode so we get timing data
#output - the output vsp file
#cs - cross session mode because we are profiling an IIS session
#user - give permissions to profile to everyone
#globaloff - start with capturing off so we don't get start up data.
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /start:Trace /output:$logLocation"\API.vsp" /cs /User:Everyone /globaloff
#restart IIS so the tracer can detect it
Write-Host "Resetting IIS..."
IISReset t80w103 /noforce
IISReset t80w103 /status
#output the status
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /status
#set up request for triggering api start up
Write-Host "Starting app via untraced request..."
$request = [System.Net.WebRequest]::Create("$siteUrl/api/v1/foo/1")
$request.ContentType = "application/json"
$request.Method = "GET"
#run an initial request to trigger api start up
$response = $request.GetResponse()
Write-Host $response.StatusCode
#enable capturing
Write-Host "Enabling capturing..."
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /globalon
#wait so everything can catch up
Write-Host "Pausing for $sleepTime seconds to let processes catch up..."
Start-Sleep -s $sleepTime
#run the load tester
Write-Host "Running SOAP UI load test"
#e - the site to test against
#s - the test suite name
#c - the test cases
#l - the loadtest to run
#r - log reports
#f - log location
#<soap ui test suite location>
$loadtestName = "LoadTest All API Methods"
& "C:\Program Files (x86)\SmartBear\SoapUI-5.1.3\bin\loadtestrunner.bat" -e $siteUrl -s "Load Test" -c "Load Test Cases" -l $loadtestName -r -f $logLocation "Api Profiler Load Test.xml"
#wait so everything can catch up
Write-Host "Pausing for $sleepTime seconds to let processes catch up..."
Start-Sleep -s $sleepTime
#disable capturing
Write-Host "Disabling capturing..."
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /globaloff
#shut down the profiler
Write-Host "Shutting down profiler. This may take some time..."
#shut down IIS so the /shutdown command works
IISReset t80w103 /noforce
IISReset t80w103 /status
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /shutdown
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCLREnv.cmd" /off /globaloff
#generate report summary
$date = Get-Date -format "yyyy-dd-M--HH-mm-ss"
$summaryReportLocation = "$logLocation\API $date"
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\VSPerfReport.exe" "$logLocation\Api.vsp" /SummaryFile /Output:"$summaryReportLocation"
#move items to shared location
$reportFolder = "\shareDrive\API\Performance Reports$date"
$profilerReport = get-childitem "$summaryReportLocation.vsps"
New-Item $reportFolder -type directory
Copy-Item $profilerReport.FullName $reportFolder
#log success
$logDate = Get-Date -format "yyyy-dd-mm HH-mm-ss"
$output = "[$logDate]" + [System.Environment]::NewLine + "Completed successfully."
$output | out-file "profiler-log.log" -append
Write-Host "Completed successfully."
}
catch{
#log error
Write-Host $_
$logDate = Get-Date -format "yyyy-dd-mm HH-mm-ss"
$output = "[$logDate]" + [System.Environment]::NewLine + $_ + [System.Environment]::NewLine
$output | out-file "profiler-log.log" -append
}
finally{
Write-Output "Done"
}
正如我所说,如果我 运行 我自己在 DEV 上手动执行上述操作,但我尝试触发它但它无法正常工作。
Enter-PSSession DEV
Invoke-Command -ComputerName DEV -FilePath "C:\PerformanceTest\profile-tracing-SoapUI.ps1"
Exit-PSSession
- The Investigation So Far
以上似乎确实触发了脚本,但我 运行 遇到了一些奇怪的问题。首先,脚本是在我执行脚本的机器上调用的(我的用于测试,TFS 构建服务器用于自动部署)而不是像我期望的那样在 DEV 上调用。这可能是我对 powershell 的误解和一个足够简单的修复 - 这意味着,除非我将脚本复制到我正在测试的网络机器(我自己的或 TFS 构建服务器)powershell 甚至在点击脚本之前就吐出一个找不到目录的错误。其次,即使我在机器上安装了脚本我试图从中触发它(确实找到脚本并开始执行)它只会到达输出 "Starting the trace..." 后跟一些关于 vsperfcmd 的信息.
Starting the trace...
Microsoft (R) VSPerf Command Version 12.0.30723 x64
Copyright (C) Microsoft Corp. All rights reserved.
Global logging control
------------------------------------------------------------
Setting global profile state to OFF.
它挂在那里,我认为调用没有完全执行,因为我必须中断它。我已经离开它 运行ning 很长一段时间(20 多分钟,本地需要几秒钟才能移动到这一点),但它从未继续超过这一点。 运行 本地脚本在该位置的输出如下所示:
Starting the trace...
Microsoft (R) VSPerf Command Version 12.0.30723 x64
Copyright (C) Microsoft Corp. All rights reserved.
Global logging control
------------------------------------------------------------
Setting global profile state to OFF.
Resetting IIS...
- The Problem
这让我相信问题所在是
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /start:Trace /output:$logLocation"\API.vsp" /cs /User:Everyone /globaloff
事实上,当我 运行 一个大大缩短的脚本来测试这个假设时,我能够验证在执行该命令后控件从未 returned 到 shell - 下面是我 运行 确认的脚本及其输出:
Enter-PSSession t80w103
Invoke-Command -ComputerName t80w103 -ScriptBlock{
try{
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /start:Trace /output:$logLocation"\API.vsp" /cs /User:Everyone /globaloff
Write-Host "No Error and Control Returned"
}
catch{
Write-Host "Error!"
}
finally{
Write-Output "Done.."
}
}
Exit-PSSession
OUTPUT:
Microsoft (R) VSPerf Command Version 12.0.30723 x64
Copyright (C) Microsoft Corp. All rights reserved.
Global logging control
------------------------------------------------------------
Setting global profile state to OFF.
该命令后没有打印任何内容。有一段时间我认为这一定意味着应用程序或 DEV 服务器出现问题,阻止它正确访问 vsperfcmd 但我检查了 DEV 任务管理器并能够找到 VSPerfMon.exe 当我 运行 命令时 是否出现在进程列表中,当我 ctrl+break 退出它时停止。所以看起来命令 是 工作,至少部分地,它只是不 return 控制以便可以执行脚本的下一部分。
所以,我的问题是,我怎样才能让它发挥作用?为什么启动profile monitor的命令执行后不控制return?这是从 TFS 自动部署构建后进行性能分析的最佳方法吗? (更新见下文)
- Additional Investigation
自从 posting 以来,我一直在自己研究这个问题,并且学到了一些有趣的东西。首先,我应该注意到 DEV 服务器上的 powershell 版本已经过时(我没有意识到这一点),所以我将它更新到版本 3。一旦我尝试 运行在 powershellISE 中的 powershellV3 上本地编写脚本我意识到它挂在 exact 中的方式与我尝试 运行 时的方式相同脚本远程。只有当我通过右键单击命令 "run with powershell" 运行 脚本时,我意识到调用 powershellV1 的脚本才能工作。不同版本的 powershell 处理我的脚本的方式似乎存在明显差异。
修改问题:为什么脚本在powershellV1中有效,但在V3中无效?为什么 V3 在 \start:trace 之后挂起而 V1 没有?当 powershell 会话直到 V2 才引入时,如何使用 V1 网络执行 运行 脚本?
回答修改后的问题让我解决了这个问题。事实证明(虽然我不知道为什么,因为我看不到源代码)VSPerfCMD.exe 不能 return 控制 Powershell 版本中的 shell ] 启动时在V1之后。这意味着调用
VSPerfCmd.exe /Start
必须在单独的 shell 中完成,否则脚本将挂起。控件仅 return 编辑一次,另一个 shell 调用关闭命令。为了解决这个问题,我使用以下代码启动分析器,然后等待我的脚本,直到它 运行ning 后再继续:
Write-Host "Starting the trace..."
#start:Trace - in tracing mode so we get timing data
#output - the output vsp file
#cs - cross session mode because we are profiling an IIS session
#user - give permissions to profile to everyone
#globaloff - start with capturing off so we don't get start up data. > is this the problem?
start powershell -ArgumentList "-ExecutionPolicy Bypass -command & 'C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe' /start:Trace /output:$logLocation\CatalogAPI.vsp /cs /User:Everyone /GlobalOff"
#wait for VSPerfCmd to start up
Write-Host "Waiting 15s for VSPerfCmd to start up..."
Start-Sleep -s 15
$counter = 0
while($counter -lt 6)
{
$e = & "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /status
if ($LASTEXITCODE -eq 0){
Write-Host $e
break
}
if ($LASTEXITCODE -eq 1 -and $counter -lt 5){
Write-Host "Still waiting. Give it 10s more ($counter)..."
Start-Sleep -s 10
$counter++
continue
}
throw "VSPerfCmd Error: $e"
}
使用上面的代码代替初始脚本中的原始跟踪启动应该允许您 运行 使用 powershell 脚本自动进行性能分析,但我不能保证结果,因为脚本有自从我最初发布这个(由于各种调查和代码改进)以来改变了一点。要让它工作,只需使用上面的代替
#enable capturing
Write-Host "Enabling capturing..."
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /globalon
tl;dr VSPerfCmd.exe /Start 不会 return 控制调用命令的 shell,直到分析服务停止在 powershell v1 之后的 powershell 版本中。如果您希望自动执行性能分析,您需要在另一个 shell 中启动性能分析器,然后等到分析器状态指示它处于活动状态,然后再继续。
因为这个问题是我尝试解决问题的尝试,所以我在下面的 post 中包含了重要的背景和调查历史。因此,我将 post 分为 3 个部分:"Background"、"Investigation So Far" 和 "Problem"。当我自己进行更多调查时,我还添加了一个 "Additional Investigation" 部分来扩展我的发现。这最终导致我自己解决了这个问题,并且我将原始的 post 作为任何尝试做同样事情的开发人员的指南。该问题最终成为 return 控制问题 VSPerfCmd.exe 在 v1.
之后的 Powershell 版本中出现
- Background
作为我的 TFS 构建(包括自动部署到我的开发 Web 服务器 DEV)的一部分,我想开始 运行 我的代码的性能测试,以便我可以看到什么时候有新的变化对我 API 的速度产生负面影响。为此,我在 DEV 上安装了 test-运行ner (SoapUI) 和 VS Team Tools,并编写了一个 Powershell 脚本,当 运行 local 在 DEV 上,生成我想要的报告。但是,我还无法触发该脚本并让它在任何其他位置运行。我的意思是说,只有登录到服务器,找到 .ps1 文件并在 Powershell 中 运行 将其 shell 才能工作。这是该脚本:
#script location+name \DEV\C$\PerformanceTest\profile-tracing-SoapUI.ps1
$startPath = Get-Location
$siteUrl = "http://api.dev.com"
$sleepTime = 5
$logLocation = "C:\reports\api"
$websiteLocation = "W:\Sites\API\Code\API\_PublishedWebsites\API\bin"
try
{
#Instrument the API dlls
Write-Host "Instrumenting DLLs..."
Get-ChildItem $websiteLocation "API*.dll" | ForEach-Object {
Set-Location -Path $websiteLocation
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSInstr.exe" $_.Name
}
#set location back to start
Set-Location -Path $startPath
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCLREnv.cmd" /GlobalTraceOn
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCLREnv.cmd" /GlobalInteractionOn
#launch the profiler on the site
Write-Host "Starting the trace..."
#start:Trace - in tracing mode so we get timing data
#output - the output vsp file
#cs - cross session mode because we are profiling an IIS session
#user - give permissions to profile to everyone
#globaloff - start with capturing off so we don't get start up data.
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /start:Trace /output:$logLocation"\API.vsp" /cs /User:Everyone /globaloff
#restart IIS so the tracer can detect it
Write-Host "Resetting IIS..."
IISReset t80w103 /noforce
IISReset t80w103 /status
#output the status
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /status
#set up request for triggering api start up
Write-Host "Starting app via untraced request..."
$request = [System.Net.WebRequest]::Create("$siteUrl/api/v1/foo/1")
$request.ContentType = "application/json"
$request.Method = "GET"
#run an initial request to trigger api start up
$response = $request.GetResponse()
Write-Host $response.StatusCode
#enable capturing
Write-Host "Enabling capturing..."
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /globalon
#wait so everything can catch up
Write-Host "Pausing for $sleepTime seconds to let processes catch up..."
Start-Sleep -s $sleepTime
#run the load tester
Write-Host "Running SOAP UI load test"
#e - the site to test against
#s - the test suite name
#c - the test cases
#l - the loadtest to run
#r - log reports
#f - log location
#<soap ui test suite location>
$loadtestName = "LoadTest All API Methods"
& "C:\Program Files (x86)\SmartBear\SoapUI-5.1.3\bin\loadtestrunner.bat" -e $siteUrl -s "Load Test" -c "Load Test Cases" -l $loadtestName -r -f $logLocation "Api Profiler Load Test.xml"
#wait so everything can catch up
Write-Host "Pausing for $sleepTime seconds to let processes catch up..."
Start-Sleep -s $sleepTime
#disable capturing
Write-Host "Disabling capturing..."
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /globaloff
#shut down the profiler
Write-Host "Shutting down profiler. This may take some time..."
#shut down IIS so the /shutdown command works
IISReset t80w103 /noforce
IISReset t80w103 /status
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /shutdown
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCLREnv.cmd" /off /globaloff
#generate report summary
$date = Get-Date -format "yyyy-dd-M--HH-mm-ss"
$summaryReportLocation = "$logLocation\API $date"
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\VSPerfReport.exe" "$logLocation\Api.vsp" /SummaryFile /Output:"$summaryReportLocation"
#move items to shared location
$reportFolder = "\shareDrive\API\Performance Reports$date"
$profilerReport = get-childitem "$summaryReportLocation.vsps"
New-Item $reportFolder -type directory
Copy-Item $profilerReport.FullName $reportFolder
#log success
$logDate = Get-Date -format "yyyy-dd-mm HH-mm-ss"
$output = "[$logDate]" + [System.Environment]::NewLine + "Completed successfully."
$output | out-file "profiler-log.log" -append
Write-Host "Completed successfully."
}
catch{
#log error
Write-Host $_
$logDate = Get-Date -format "yyyy-dd-mm HH-mm-ss"
$output = "[$logDate]" + [System.Environment]::NewLine + $_ + [System.Environment]::NewLine
$output | out-file "profiler-log.log" -append
}
finally{
Write-Output "Done"
}
正如我所说,如果我 运行 我自己在 DEV 上手动执行上述操作,但我尝试触发它但它无法正常工作。
Enter-PSSession DEV
Invoke-Command -ComputerName DEV -FilePath "C:\PerformanceTest\profile-tracing-SoapUI.ps1"
Exit-PSSession
- The Investigation So Far
以上似乎确实触发了脚本,但我 运行 遇到了一些奇怪的问题。首先,脚本是在我执行脚本的机器上调用的(我的用于测试,TFS 构建服务器用于自动部署)而不是像我期望的那样在 DEV 上调用。这可能是我对 powershell 的误解和一个足够简单的修复 - 这意味着,除非我将脚本复制到我正在测试的网络机器(我自己的或 TFS 构建服务器)powershell 甚至在点击脚本之前就吐出一个找不到目录的错误。其次,即使我在机器上安装了脚本我试图从中触发它(确实找到脚本并开始执行)它只会到达输出 "Starting the trace..." 后跟一些关于 vsperfcmd 的信息.
Starting the trace...
Microsoft (R) VSPerf Command Version 12.0.30723 x64
Copyright (C) Microsoft Corp. All rights reserved.
Global logging control
------------------------------------------------------------
Setting global profile state to OFF.
它挂在那里,我认为调用没有完全执行,因为我必须中断它。我已经离开它 运行ning 很长一段时间(20 多分钟,本地需要几秒钟才能移动到这一点),但它从未继续超过这一点。 运行 本地脚本在该位置的输出如下所示:
Starting the trace...
Microsoft (R) VSPerf Command Version 12.0.30723 x64
Copyright (C) Microsoft Corp. All rights reserved.
Global logging control
------------------------------------------------------------
Setting global profile state to OFF.
Resetting IIS...
- The Problem
这让我相信问题所在是
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /start:Trace /output:$logLocation"\API.vsp" /cs /User:Everyone /globaloff
事实上,当我 运行 一个大大缩短的脚本来测试这个假设时,我能够验证在执行该命令后控件从未 returned 到 shell - 下面是我 运行 确认的脚本及其输出:
Enter-PSSession t80w103
Invoke-Command -ComputerName t80w103 -ScriptBlock{
try{
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /start:Trace /output:$logLocation"\API.vsp" /cs /User:Everyone /globaloff
Write-Host "No Error and Control Returned"
}
catch{
Write-Host "Error!"
}
finally{
Write-Output "Done.."
}
}
Exit-PSSession
OUTPUT:
Microsoft (R) VSPerf Command Version 12.0.30723 x64
Copyright (C) Microsoft Corp. All rights reserved.
Global logging control
------------------------------------------------------------
Setting global profile state to OFF.
该命令后没有打印任何内容。有一段时间我认为这一定意味着应用程序或 DEV 服务器出现问题,阻止它正确访问 vsperfcmd 但我检查了 DEV 任务管理器并能够找到 VSPerfMon.exe 当我 运行 命令时 是否出现在进程列表中,当我 ctrl+break 退出它时停止。所以看起来命令 是 工作,至少部分地,它只是不 return 控制以便可以执行脚本的下一部分。
所以,我的问题是,我怎样才能让它发挥作用?为什么启动profile monitor的命令执行后不控制return?这是从 TFS 自动部署构建后进行性能分析的最佳方法吗? (更新见下文)
- Additional Investigation
自从 posting 以来,我一直在自己研究这个问题,并且学到了一些有趣的东西。首先,我应该注意到 DEV 服务器上的 powershell 版本已经过时(我没有意识到这一点),所以我将它更新到版本 3。一旦我尝试 运行在 powershellISE 中的 powershellV3 上本地编写脚本我意识到它挂在 exact 中的方式与我尝试 运行 时的方式相同脚本远程。只有当我通过右键单击命令 "run with powershell" 运行 脚本时,我意识到调用 powershellV1 的脚本才能工作。不同版本的 powershell 处理我的脚本的方式似乎存在明显差异。
修改问题:为什么脚本在powershellV1中有效,但在V3中无效?为什么 V3 在 \start:trace 之后挂起而 V1 没有?当 powershell 会话直到 V2 才引入时,如何使用 V1 网络执行 运行 脚本?
回答修改后的问题让我解决了这个问题。事实证明(虽然我不知道为什么,因为我看不到源代码)VSPerfCMD.exe 不能 return 控制 Powershell 版本中的 shell ] 启动时在V1之后。这意味着调用
VSPerfCmd.exe /Start
必须在单独的 shell 中完成,否则脚本将挂起。控件仅 return 编辑一次,另一个 shell 调用关闭命令。为了解决这个问题,我使用以下代码启动分析器,然后等待我的脚本,直到它 运行ning 后再继续:
Write-Host "Starting the trace..."
#start:Trace - in tracing mode so we get timing data
#output - the output vsp file
#cs - cross session mode because we are profiling an IIS session
#user - give permissions to profile to everyone
#globaloff - start with capturing off so we don't get start up data. > is this the problem?
start powershell -ArgumentList "-ExecutionPolicy Bypass -command & 'C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe' /start:Trace /output:$logLocation\CatalogAPI.vsp /cs /User:Everyone /GlobalOff"
#wait for VSPerfCmd to start up
Write-Host "Waiting 15s for VSPerfCmd to start up..."
Start-Sleep -s 15
$counter = 0
while($counter -lt 6)
{
$e = & "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /status
if ($LASTEXITCODE -eq 0){
Write-Host $e
break
}
if ($LASTEXITCODE -eq 1 -and $counter -lt 5){
Write-Host "Still waiting. Give it 10s more ($counter)..."
Start-Sleep -s 10
$counter++
continue
}
throw "VSPerfCmd Error: $e"
}
使用上面的代码代替初始脚本中的原始跟踪启动应该允许您 运行 使用 powershell 脚本自动进行性能分析,但我不能保证结果,因为脚本有自从我最初发布这个(由于各种调查和代码改进)以来改变了一点。要让它工作,只需使用上面的代替
#enable capturing
Write-Host "Enabling capturing..."
& "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Performance Tools\x64\VSPerfCmd.exe" /globalon
tl;dr VSPerfCmd.exe /Start 不会 return 控制调用命令的 shell,直到分析服务停止在 powershell v1 之后的 powershell 版本中。如果您希望自动执行性能分析,您需要在另一个 shell 中启动性能分析器,然后等到分析器状态指示它处于活动状态,然后再继续。