问题
I'm writing a Visual Studio 2012 add-in which extends Build Explorer - basically, I add a context menu option for every build (completed or running, but not queued). Following a blog post about doing this in VS2010, I managed to do so for builds that appear in Builder Explorer - hooray!
Now, my context menu also appear in Team Explorer's Builds
pages, My Builds
section. However, when I get the callback, I can't find the actual builds anywhere!
Here's my beforeQueryStatus event handler, where I try to find out whether I have a build to show or not:
private void OpenCompletedInBuildExplorerBeforeQueryStatus(object sender, EventArgs e)
{
var cmd = (OleMenuCommand)sender;
var vsTfBuild = (IVsTeamFoundationBuild)GetService(typeof(IVsTeamFoundationBuild));
// This finds builds in Build Explorer window
cmd.Enabled = (vsTfBuild.BuildExplorer.CompletedView.SelectedBuilds.Length == 1
&& vsTfBuild.BuildExplorer.QueuedView.SelectedBuilds.Length == 0); // No build _requests_ are selected
// This tries to find builds in Team Explorer's Builds page, My Builds section
var teamExplorer = (ITeamExplorer)GetService(typeof(ITeamExplorer));
var page = teamExplorer.CurrentPage as Microsoft.TeamFoundation.Controls.WPF.TeamExplorer.TeamExplorerPageBase;
var vm = page.ViewModel;
// does not compile: 'Microsoft.TeamFoundation.Build.Controls.BuildsPageViewModel' is inaccessible due to its protection level
var vm_private = vm as Microsoft.TeamFoundation.Build.Controls.BuildsPageViewModel;
// But debugger shows that if it did, my builds would be here:
var builds = vm_private.MyBuilds;
}
- Is there a way to get the list of builds?
- More generally, is there a way to get some "window which this context menu belong to"? Currently I'm just looking around in parts of VS I assume would have builds...
回答1:
I managed to get the build using reflection:
var teamExplorer = (ITeamExplorer)GetService(typeof(ITeamExplorer));
var BuildsPage = teamExplorer.CurrentPage as Microsoft.TeamFoundation.Controls.WPF.TeamExplorer.TeamExplorerPageBase;
var PageViewModel = BuildsPage.ViewModel as Microsoft.TeamFoundation.Controls.WPF.TeamExplorer.TeamExplorerPageViewModelBase;
// PageViewModel is actually Microsoft.TeamFoundation.Build.Controls.BuildsPageViewModel. But, it's private, so get SelectedBuilds through reflection
var SelectedBuilds = PageViewModel.GetType().GetProperty("SelectedBuilds").GetValue(PageViewModel) as System.Collections.IList;
if (SelectedBuilds.Count != 1)
{
cmd.Enabled = false;
return;
}
object BuildModel = SelectedBuilds[0];
// BuildModel is actually Microsoft.TeamFoundation.Build.Controls.BuildModel. But, it's private, so get UriToOpen through reflection
var BuildUri = BuildModel.GetType().GetProperty("UriToOpen").GetValue(BuildModel) as Uri;
// TODO: Use BuildUri...
cmd.Enabled = true;
来源:https://stackoverflow.com/questions/16466899/finding-builds-in-team-explorers-my-builds