0

Наша компания недавно обновила обновление TFS до 2015 года. После этого пункт контекстного меню с именем Drop folder исчез из завершенных сборок. Я ничего не нашел об этом и о том, как вернуть его. Когда я нажимаю Open на завершенной сборке, VS открывает веб-версию TFS, где я вынужден щелкнуть по меню и скопировать папку папки с папкой вручную. Поэтому я решил написать простое расширение, которое добавит этот элемент в меню.
Некоторые поисковики привезли меня в this page. Но мне кажется, что пример кода является довольно старая и не работает в VS2015:Visual Studio 2015 build drop location

IVsTeamFoundationBuild vsTfBuild = (IVsTeamFoundationBuild)GetService(typeof(IVsTeamFoundationBuild)); 
IBuildDetail[] builds = vsTfBuild.BuildExplorer.CompletedView.SelectedBuilds; 

Property SelectedBuilds всегда пусто. Я полагаю, что это связано с старым окном от VS2010. Он возвращает элементы, которые являются экземпляром интерфейса IBuildDetail.
Так что я нашел этот кусок кода here:

var teamExplorer = (ITeamExplorer)ServiceProvider.GetService(typeof(ITeamExplorer)); 
var page = teamExplorer.CurrentPage; 
var buildsPageExt = (IBuildsPageExt)page.GetExtensibilityService(typeof(IBuildsPageExt)); 
var build = buildsPageExt.SelectedBuilds[0]; 

Здесь build является экземпляром IBuildModel интерфейса. Ему не хватает собственности DropLocation.

Есть ли способ найти место для удаления выбранной сборки? Или, может быть, последняя сборка?

+0

Какую версию API вы используете? –

+0

Как это проверить? Я использую библиотеки из папки VS2015. Все библиотеки DLL версии 14.0.0.0. –

ответ

0

Таким образом, после перекопа через API TFS я закончил с этим обходным решением.

private void MenuItemCallback(object sender, EventArgs e) 
    { 
     var context = (ITeamFoundationContextManager)ServiceProvider.GetService(typeof(ITeamFoundationContextManager)); 
     IBuildServer buildServer = context.CurrentContext.TeamProjectCollection.GetService<IBuildServer>(); 
     var teamExplorer = (ITeamExplorer)ServiceProvider.GetService(typeof(ITeamExplorer)); 
     var buildsPageExt = (IBuildsPageExt)teamExplorer.CurrentPage.GetExtensibilityService(typeof(IBuildsPageExt)); 
     var menuCommand = (MenuCommand)sender; 

     if (menuCommand.CommandID.Guid == CommandSetCompleted) 
     { 
      foreach (var buildDetail in buildsPageExt.SelectedBuilds) 
       Process.Start("explorer.exe", GetBuild(buildServer, buildDetail).DropLocation); 
     } 

     if (menuCommand.CommandID.Guid == CommandSetFavorite) 
     { 
      var definitions = buildsPageExt.SelectedFavoriteDefinitions.Concat(buildsPageExt.SelectedXamlDefinitions).ToArray(); 

      foreach (var build in GetLatestSuccessfulBuild(buildServer, definitions)) 
       Process.Start("explorer.exe", build.DropLocation); 
     } 
    } 

    private IBuildDetail GetBuild(IBuildServer buildServer, IBuildModel buildModel) 
    { 
     Uri buildUri = new Uri(buildModel.GetType().GetProperty("UriToOpen").GetValue(buildModel).ToString()); 
     return buildServer.GetBuild(buildUri); 
    } 

    private IBuildDetail[] GetLatestSuccessfulBuild(IBuildServer buildServer, IDefinitionModel[] buildDefinitions) 
    { 
     var spec = buildServer.CreateBuildDetailSpec(buildDefinitions.Select(bd => bd.Uri)); 
     spec.MaxBuildsPerDefinition = 1; 
     spec.QueryOrder = BuildQueryOrder.FinishTimeDescending; 
     spec.Status = BuildStatus.Succeeded; 

     var builds = buildServer.QueryBuilds(spec); 

     return builds.Builds; 
    } 
1

Вы можете использовать IBuildDedetail.DropLocation в .NET client libraries for Visual Studio Team Services (and TFS). Базовый код для справки:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.TeamFoundation.Build.Client; 
using Microsoft.TeamFoundation.Client; 

namespace BuildAPI 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string project = "http://xxx.xxx.xxx.xxx"; 
      TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project)); 
      IBuildServer ibs = tpc.GetService<IBuildServer>(); 
      var builds = ibs.QueryBuilds("TeamProjectName"); 
      foreach (IBuildDetail ibd in builds) 
      { 
       Console.WriteLine(ibd.DropLocation); 
       Console.ReadLine(); 
      } 
     } 
    } 
} 
+0

У нас есть 635 строковых определений. Многие из них регулярно строятся. Я хочу, чтобы выпадало местоположение для одной конкретной выбранной сборки. Откуда я знаю, какой из них выбрать из коллекции 'builds'? –

+1

@JohnPreston Затем вы можете использовать метод GetBuild для получения указанной сборки. См. Эту ссылку: https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.client.ibuildserver.getbuild(v=vs.120).aspx. А также, поскольку вы используете TFS2015, он поддерживает Rest API, вы также можете использовать этот API для получения этой информации. Ссылка: https://www.visualstudio.com/integrate/api/build/builds#Getbuilddetails –

+0

'GetBuild' работает со строковым URI. 'IBuildModel' не содержит этого свойства. Но частный класс BuildModel делает. Я использовал отражение, чтобы получить его значение. Позор Microsoft для такого плохого API. Спасибо за помощь. –