Как я могу рассматривать MSB3245 (не удалось разрешить ссылку) предупреждение как ошибку?
Мой вопрос основан на другом вопросе, но я хочу сделать наоборот: скажите msbuild, что нужно воспринимать предупреждение как ошибку, а не подавлять конкретное предупреждение msbuild.
Однако все, что я вижу до сих пор, говорит /p:WarningsAsErrors
только принимает в CSC предупреждения и ошибки. Я пытался просто бросить MSB
и гуглить, какое число может пойти туда на работу, но не повезло.
Есть ли способ трактовать предупреждение "ссылка на сборку не найдена" из msbuild (командная строка) как ошибку?
2 ответа
В последнее время мне нужно было нечто подобное (действующее на определенных событиях журнала), но я не мог найти чистого решения, главным образом, потому что я не понял, как программно получить доступ к регистраторам в процессе 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
Мне просто нужно было это снова, но я больше не мог найти исходную 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>
update В ответ на комментарии: пробуя это снова сегодня, я не уверен, что оригинальный код действительно когда-либо работал (хорошо, он работает для показанного примера сообщения, но не для фактического предупреждения MSB3245), так как он перехватывает только события сообщения, тогда как ResolveAssemblyReference выдает фактическое событие предупреждения и, кроме того, номер предупреждения обычно не содержится в сообщении. Это делает трюк, хотя:
public class ScanLogger : Logger
{
public override void Initialize( IEventSource eventSource )
{
eventSource.WarningRaised += ( s, e ) => Common.errorsOccurred |= e.Code == "MSB3245";
}
}
Кажется, что сообщение, связанное с этим предупреждением, не является предупреждением:
Если эта ссылка требуется вашим кодом, вы можете получить ошибки компиляции
не совсем правильно. Если отсутствующая ссылка является темой WPF, вместо этого вы получите ошибку времени выполнения (System.IO.FileNotFoundException).
Кроме того, если вы специально ищете MSB3245, вы получите:
CSC: предупреждение CS1691: "MSB3245" не является допустимым номером предупреждения