2013-07-05 17 views
8

Moje pytanie jest oparte na another one, ale chcę zrobić przeciwnie: powiedz msbuild, aby potraktować ostrzeżenie jako błąd, zamiast tłumienia określonego ostrzeżenia msbuild.Jak traktować ostrzeżenie MSB3245 (nie można rozwiązać odwołania) jako błąd?

Jednak wszystko, co widzę do tej pory, mówi, że /p:WarningsAsErrors przyjmuje tylko ostrzeżenia i błędy csc. Próbowałem po prostu upuścić MSB i googling, aby sprawdzić, jaki numer może tam wejść, ale bez powodzenia.

Czy istnieje sposób, aby potraktować ostrzeżenie "odniesienie do zestawu nie znaleziono" z msbuild (wiersza polecenia) jako błąd?

Odpowiedz

8

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"; 
    } 
} 
+0

czy istnieje sposób, aby dodać ten proces do poziomu rozwiązania zamiast poziomu projektu? – Maslow

+0

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

+0

@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

1

Wydaje się, że wiadomość związana z tym ostrzeżeniem, że nie jest to ostrzeżenie:

Jeśli to odniesienie jest wymagane przez kod, można uzyskać kompilacji błędy

, nie jest całkiem poprawne. Jeśli brakujące odniesienie jest motywem WPF, zostanie wyświetlony błąd run-time (System.IO.FileNotFoundException).

Tak na marginesie, jeśli specjalnie szukać MSB3245 dostaniesz:

CSC: ostrzeżenie CS1691: „MSB3245” nie jest poprawnym numerem ostrzeżenie

Powiązane problemy