Ответ 1
Предупреждения MSBuild (все начинаются с MSB *), в отличие от предупреждений CSC, не могут быть подавлены и не допущены к ошибкам. По этой причине задача ResolveAssemblyReference
печатает свои сообщения "на лету" и не агрегирует их.
Единственное возможное решение - чтение файлов журнала MSBuild, созданных во время сборки TFS.
Я считаю, что наиболее элегантным решением является реализация пользовательской сборки CodeActivity
. Ниже приведена простая операция, которая выводит на результат любые файлы, содержащие заданный SearchString
:
using System;
using System.Activities;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
namespace MyBuildActivities.FileSystem
{
[BuildActivity(HostEnvironmentOption.Agent)]
public sealed class ReadStringFromFile : CodeActivity
{
[RequiredArgument]
public InArgument<IEnumerable<string>> Files { get; set; }
[RequiredArgument]
public InArgument<string> SearchString { get; set; }
public OutArgument<string> Result { get; set; }
protected override void Execute(CodeActivityContext context)
{
var files = context.GetValue(Files);
var searchString = context.GetValue(SearchString);
var list =
(files.Where(file => File.ReadAllText(file).Contains(searchString))
.Select(file => string.Format("{0} was found at {1}", searchString, file))).ToList();
if(list.Count > 0)
Result.Set(context, string.Join(Environment.NewLine, list));
}
}
}
Объявлен в шаблоне процесса сборки так:
xmlns:cfs="clr-namespace:MyBuildActivities.FileSystem;assembly=MyBuildActivities"
Вызывается только в конце последовательности Compile and Test for Configuration
:
<Sequence DisplayName="Handle MSBuild Errors">
<Sequence.Variables>
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="logFiles" />
<Variable x:TypeArguments="x:String" Name="readStringFromFileResult" />
</Sequence.Variables>
<mtbwa:FindMatchingFiles DisplayName="Find Log Files" MatchPattern="[String.Format("{0}\**\*.log", logFileDropLocation)]" Result="[logFiles]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<cfs:ReadStringFromFile Files="[logFiles]" SearchString="MSB3245" Result="[readStringFromFileResult]" />
<mtbwa:WriteBuildMessage DisplayName="Write Result" Message="[readStringFromFileResult]" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" />
<If Condition="[readStringFromFileResult.Count > 0]" DisplayName="If SearchString Was Found" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Throw DisplayName="Throw Exception" Exception="[New Exception(readStringFromFileResult)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
</Sequence>
Я тестировал это на TFS 2012, хотя он должен работать и для TFS 2010.