Ostatnio potrzebowałem czegoś podobnego (działającego w określonych zdarzeniach logujących), ale nie mogłem znaleźć czystego rozwiązania głównie dlatego, że nie znalazłem sposobu, aby programowo uzyskać dostęp do rejestratorów w procesie msbuild. Ja przyszedłem się z tym jednak, dostosowany do problemu zasada brzmi:
- zainstalować skanowanie niestandardowe rejestratora za ostrzeżenie
- build
- ustawić statyczny flagę, jeśli ostrzeżenie pojawia
- mieć niestandardowe zadanie sprawdzić tę flagę i podnieść błąd, czy to na
może wydawać trudne, ale kod jest dość proste:
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;
}
}
}
Oto przykładowy skrypt msbuild używając go:
<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>
I wywołać ją tak:
msbuild /logger:Foo.dll my.proj
zmienił prostu potrzebne to jeszcze raz, ale nie mógł znaleźć oryginalny dll ani plik projektu itd. - Pomyślałem, że przechowywanie kodu i najprostszych instrukcji kompilacji w gitarze i budowanie go w locie, gdy jest to potrzebne, jest prawdopodobnie czystsze. Więc w zasadzie zapisać powyższy kod w ciągu customlogger.cs plik, a następnie gdzieś w procesie kompilacji, zanim skutecznie powołując msbuild z niestandardowego rejestratora, budować go używając
<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>
aktualizacji W odpowiedzi na komentarze: stara to ponownie dziś nie jestem pewien, czy oryginalny kod faktycznie działał (dobrze, robi to dla przykładowego komunikatu, ale nie dla aktualnego ostrzeżenia MSB3245), ponieważ przechwytuje tylko zdarzenia komunikatów, podczas gdy ResolveAssemblyReference emituje faktyczne zdarzenie ostrzegawcze, a ponadto numer ostrzegawczy isn zazwyczaj zawarte w wiadomości. To załatwia sprawę jednak:
public class ScanLogger : Logger
{
public override void Initialize(IEventSource eventSource)
{
eventSource.WarningRaised += (s, e) => Common.errorsOccurred |= e.Code == "MSB3245";
}
}
czy istnieje sposób, aby dodać ten proces do poziomu rozwiązania zamiast poziomu projektu? – Maslow
Zasadniczo zdefiniujesz tę logikę we wspólnym pliku, a następnie zaimportujesz ten plik do każdego projektu. Nie jestem pewien co do najlepszego sposobu, aby zrobić to automatycznie na podstawie rozwiązania, może coś takiego: http://stackoverflow.com/questions/18249027/import-targets-file-from-command-line-in-msbuild lub http : //dotnet.geir-sorensen.net/2010/04/msbuild-custom-targets.html – stijn
@stijn Używam tego kodu i pracuję nad jego przykładem (gdzie sztucznie wysyłam wiadomość zawierającą MSB3245). Jednak gdy uruchomię go na serio, żadna taka wiadomość nie przychodzi. Loguję się (do pliku) każdej wiadomości otrzymanej przez rejestrator i nie pojawiają się żadne ciekawe (z ostrzeżeniami itp.). Próbowałem też podłączyć się do eventSource.AnyEventRaised i eventSource.WarningRaised, ale nie mają ostrzeżenia, które próbuję znaleźć. Wygląda na to, że zachowanie się zmieniło. – fastmultiplication