Как заставить MSBuild НЕ останавливаться на ошибке при. NET решении - PullRequest
1 голос
/ 23 января 2020

Я работаю над настройкой собственного сервера сборки, адаптированной к потребностям команды. Он должен автоматически создавать наши решения. net. Я делаю все возможное, чтобы ничего не менять в .sln или файлах проекта.

Очевидным инструментом для сборки является msbuild. Я понял, что на самом деле успешно скомпилировал наши решения из файлов .sln.

Следующим шагом является тестирование сценария, когда некоторые проекты решения не работают. И тут я столкнулся со странной разницей в поведении между devenv и msbuild в следующей ситуации. Есть 3 проекта, где 2-й зависит от 1-го, а 3-й является независимым и не работает. devenv компилирует 1-й и 2-й и завершает работу 3-го, как и ожидалось; msbuild компилирует 1-е, терпит неудачу 3-е и - неожиданно - не пытается 2-е.

Пример решения (4 файла: Complete.sln, 1.csproj, 2.csproj, 3.csproj)

--- 1.csproj
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <UpgradeBackupLocation>
    </UpgradeBackupLocation>
    <OldToolsVersion>2.0</OldToolsVersion>
  </PropertyGroup>
  <Target Name="Build">
    <Message Importance="High" Text="Project 1" />
  </Target>
</Project>
--- 2.csproj
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <UpgradeBackupLocation>
    </UpgradeBackupLocation>
    <OldToolsVersion>2.0</OldToolsVersion>
  </PropertyGroup>
  <Target Name="Build">
    <Message Importance="High" Text="Project 2" />
  </Target>
</Project>
--- 3.csproj
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <UpgradeBackupLocation>
    </UpgradeBackupLocation>
    <OldToolsVersion>2.0</OldToolsVersion>
  </PropertyGroup>
  <Target Name="Build">
    <Message Importance="High" Text="Project 3" />
    <Error Text="Build failed" />
  </Target>
</Project>
--- Complete.sln

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "1", "1.csproj", "{AA88BE9A-5006-4CCE-8871-A67F413DBADF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2", "2.csproj", "{BAF51480-4B90-454A-96F5-E63A05A486EF}"
    ProjectSection(ProjectDependencies) = postProject
        {AA88BE9A-5006-4CCE-8871-A67F413DBADF} = {AA88BE9A-5006-4CCE-8871-A67F413DBADF}
    EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "3", "3.csproj", "{12C30CFB-7387-4CD2-81D4-87E14209C408}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x86 = Debug|x86
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {AA88BE9A-5006-4CCE-8871-A67F413DBADF}.Debug|x86.ActiveCfg = Debug|x86
        {AA88BE9A-5006-4CCE-8871-A67F413DBADF}.Debug|x86.Build.0 = Debug|x86
        {BAF51480-4B90-454A-96F5-E63A05A486EF}.Debug|x86.ActiveCfg = Debug|x86
        {BAF51480-4B90-454A-96F5-E63A05A486EF}.Debug|x86.Build.0 = Debug|x86
        {12C30CFB-7387-4CD2-81D4-87E14209C408}.Debug|x86.ActiveCfg = Debug|x86
        {12C30CFB-7387-4CD2-81D4-87E14209C408}.Debug|x86.Build.0 = Debug|x86
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {75E95C15-489D-4D3F-82CA-735FB7B88910}
    EndGlobalSection
EndGlobal

Вывод на консоль из «Командная строка разработчика для VS 2019» выглядит следующим образом:

e>devenv /Build Debug Complete.sln

Microsoft Visual Studio 2019 Version 16.4.3.
Copyright (C) Microsoft Corp. All rights reserved.
1>------ Build started: Project: 1, Configuration: Debug x86 ------
2>------ Build started: Project: 3, Configuration: Debug x86 ------
1>  Project 1
2>  Project 3
2>C:\temp\msbuild\TestSolution\Complete\3.csproj(11,2): error : Build failed
3>------ Build started: Project: 2, Configuration: Debug x86 ------
3>  Project 2
========== Build: 2 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
>msbuild Complete.sln /p:Configuration=Debug /p:Platform=x86 /m
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 23.01.2020 11:10:38.
     1>Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" on node 1 (default targets).
     1>ValidateSolutionConfiguration:
         Building solution configuration "Debug|x86".
     1>Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (1) is building "c:\temp\msbuild\TestSolution\Complete\1.cs
       proj" (2) on node 1 (default targets).
     2>Build:
         Project 1
     2>Done Building Project "c:\temp\msbuild\TestSolution\Complete\1.csproj" (default targets).
     1>Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (1) is building "c:\temp\msbuild\TestSolution\Complete\3.cs
       proj" (3) on node 2 (default targets).
     3>Build:
         Project 3
     3>c:\temp\msbuild\TestSolution\Complete\3.csproj(11,5): error : Build failed
     3>Done Building Project "c:\temp\msbuild\TestSolution\Complete\3.csproj" (default targets) -- FAILED.
     1>Done Building Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (default targets) -- FAILED.

Build FAILED.

       "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (default target) (1) ->
       "c:\temp\msbuild\TestSolution\Complete\3.csproj" (default target) (3) ->
       (Build target) ->
         c:\temp\msbuild\TestSolution\Complete\3.csproj(11,5): error : Build failed

    0 Warning(s)
    1 Error(s)

Time Elapsed 00:00:00.65

Обратите внимание, что в msbuild выводится сообщение Project 2.

Есть ли (ненавязчивый) способ заставить msbuild продолжать компиляцию других проектов?

Лучшее, что я до сих пор придумывал, - это создание Directory.Solution.targets в какой-то папке вверх от Complete.sln (см. msdn ) со следующим содержимым.

<Project>
  <Target Name="SetSkip">
    <ItemGroup>
      <ProjectReference Update="*">
        <SkipNonexistentProjects>Build</SkipNonexistentProjects>
      </ProjectReference>
    </ItemGroup>
  </Target>
  <Target Name="BuildAll" DependsOnTargets="SetSkip">
    <CallTarget Targets="Build"/>
  </Target>
</Project>

Примечание SkipNonexistentProjects установлено на Build, а не True. Когда установлено значение True, второй проект пропускается с Skipping project "2.csproj.metaproj" because it was not found..

, а затем вызывается msbuild с /t:BuildAll вместо /t:Build. Но мне нужно было бы сделать это для каждого возможного решения и каждой возможной цели, и я бы действительно хотел какой-нибудь лучший способ, возможно, переключатель командной строки, который я пока не смог найти (/p:ContinueOnError=true;StopOnFirstFailure=false;SkipNonexistentProjects=true не помогает).

ОБНОВЛЕНИЕ улучшил мой обходной путь: теперь требуется только один дополнительный файл в папке root.

Ответы [ 2 ]

0 голосов
/ 30 января 2020

Этот ответ цитирует мое обходное решение в самом вопросе, чтобы улучшить его наглядность (как предложено в комментарии к другому ответу).

Лучшее, что я получил до сих пор создает Directory.Solution.targets в какой-то папке вверх от Complete.sln (см. msdn ) со следующим содержимым.

<Project>
  <Target Name="SetSkip">
    <ItemGroup>
      <ProjectReference Update="*">
        <SkipNonexistentProjects>Build</SkipNonexistentProjects>
      </ProjectReference>
    </ItemGroup>
  </Target>
  <Target Name="BuildAll" DependsOnTargets="SetSkip">
    <CallTarget Targets="Build"/>
  </Target>
  <Target Name="RebuildAll" DependsOnTargets="SetSkip">
    <CallTarget Targets="Rebuild"/>
  </Target>
  <Target Name="CleanAll" DependsOnTargets="SetSkip">
    <CallTarget Targets="Clean"/>
  </Target>
</Project>

Примечание SkipNonexistentProjects установлено на Build не True. Когда установлено значение True, второй проект пропускается с Skipping project "2.csproj.metaproj" because it was not found..

, а затем вызов msbuild с /t:BuildAll вместо /t:Build создает все, что может, как и ожидалось.

Это достаточно хорошее решение для меня, хотя я все равно предпочел бы какой-то путь без определения альтернативных целей сборки / перестройки.

0 голосов
/ 24 января 2020

Как заставить MSBuild НЕ останавливаться при ошибке при включении. NET решение

Ответ - НЕТ , поскольку похоже на одну проблему, касающуюся msbuild. Таким образом, у нас может быть только обходной путь вместо решения ...

Я могу воспроизвести ту же проблему на моей машине с VS2019 и msbuild 16.0. Поскольку все работает хорошо с использованием devenv, я думаю, вы можете опубликовать одну проблему здесь в Msbuild Team. (Я пробовал с несколькими свойствами msbuild, но они не работают, поэтому я думаю, что это проблема)

И вот несколько временных обходных путей:

1.Если у вас не слишком много проектов в В этом решении вы можете использовать переключатель target для создания определенных c проектов с указанным c порядком, проверьте этот документ .

Для меня я использую команду, подобную msbuild Library.sln -target:LibraryA;LibraryB;LibraryC /p:Configuration=Debug /p:Platform="Any CPU" -m и затем msbuild создаст LibraryB.

2.Если у вас много проектов в одном решении, вы можете создать пользовательский файл сценария сборки build.proj в папке решения с таким содержимым:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="CustomBuild">
<MSBuild Projects="LibraryA\LibraryA.vbproj" Properties="Configuration=$(Configuration);Platform=$(Platform)"/>
<MSBuild Projects="LibraryB\LibraryB.vbproj" Properties="Configuration=$(Configuration);Platform=$(Platform)"/>
<MSBuild Projects="LibraryC\LibraryC.vbproj" Properties="Configuration=$(Configuration);Platform=$(Platform)"/>

Затем используйте команду наподобие msbuild build.proj / p: Configuration = xx; Platform = xx для создания этих проектов.

Вы можете попробовать эти временные решения временно или использовать Команда devenv для вашей сборки. Но для самой проблемы решение должно быть исправлено командой msbuild, если я не понимаю неправильно ... Надеюсь, что все выше помогает :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...