最近我需要类似的东西(对某些日志事件采取行动),但我找不到一个干净的解决方案,主要是因为我还没有弄清楚如何在 msbuild 过程中以编程方式访问记录器。我确实想出了这个,适应你的问题,原则是:
- 安装自定义记录器扫描警告
- 构建
- 如果出现警告,设置静态标志
- 有一个自定义任务检查该标志并在它打开时引发错误
可能听起来很难,但代码很简单:
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Foo
{
public static class Common
{
public static bool errorsOccurred = false;
}
public class ScanLogger : Logger
{
public override void Initialize( IEventSource eventSource )
{
eventSource.MessageRaised += ( s, e ) =>
Common.errorsOccurred |= e.Message.Contains( "MSB3245" );
}
}
public class CheckErrors : Task
{
public override bool Execute()
{
if( Common.errorsOccurred == false )
return true;
Log.LogError( "errorsOccurred = true" );
return false;
}
}
}
这是一个使用它的示例 msbuild 脚本:
<UsingTask TaskName="Foo.CheckErrors" AssemblyFile="Foo.dll"/>
<Target Name="MyBuild">
<Message Text="MSB3245"/> <!-- simulate the build warning -->
<Foo.CheckErrors /> <!-- this will trigger an error -->
</Target>
然后你像这样调用它:
msbuild /logger:Foo.dll my.proj
edit 我只是再次需要它,但再也找不到原始 dll 或项目文件等 - 我想将代码和最简单的构建指令存储在 git 中,并在需要时即时构建它可能更清洁。因此,基本上将上面的代码存储在文件 customlogger.cs 中,然后在构建过程中的某个位置,在使用自定义记录器有效调用 msbuild 之前,使用
构建它
<Target Name="BuildCustomLoggerDll">
<Csc Sources="$(MSBuildThisFileDirectory)customlogger.cs"
References="System.dll;mscorlib.dll;Microsoft.Build.Framework.dll;Microsoft.Build.Utilities.v4.0.dll"
TargetType="Library" OutputAssembly="$(MSBuildThisFileDirectory)CustomLogger.dll"/>
</Target>
更新回应 cmets:今天再次尝试我不确定原始代码是否真的有效(好吧,它适用于显示的示例消息,但不适用于实际的警告 MSB3245),因为它仅挂钩消息事件,而 ResolveAssemblyReference 发出实际的警告事件,而且警告编号通常不包含在消息中。不过,这可以解决问题:
public class ScanLogger : Logger
{
public override void Initialize( IEventSource eventSource )
{
eventSource.WarningRaised += ( s, e ) => Common.errorsOccurred |= e.Code == "MSB3245";
}
}