【问题标题】:Can you prevent MSBuild.exe from running Build Events?你能阻止 MSBuild.exe 运行生成事件吗?
【发布时间】:2010-12-16 10:58:38
【问题描述】:

我正在通过脚本构建多个项目,偶尔使用自定义构建事件会给构建系统带来很大的困难。如果可能的话,我想调用 MSBuild.exe 以阻止任何构建事件的执行。从长远来看,这对于构建自动化来说不是问题——带有构建事件的项目提交者会被预先警告,这种恶意行为是违反规则的。

简而言之,有没有一种方法可以调用 MSBuild 来阻止执行任何自定义构建步骤(如果存在)?

更新:

我考虑过对项目文件进行就地(自动)编辑,但更喜欢将三个中的每一个都设置为“从构建中排除”(请参阅​​构建事件选项)的命令行等效项事件。

【问题讨论】:

    标签: events build msbuild


    【解决方案1】:

    Pre/PostBuildEvents 是属性,因此要覆盖它们,只需将它们从命令行设置为空字符串。

    msbuild foo.sln /p:PreBuildEvent= /p:PostBuildEvent=
    

    【讨论】:

    • 这似乎对我不起作用,我使用的是 MSBuild v4.0.30319.17929
    • 使用 msbuild foo.sln /p:PreBuildEvent="" /p:PostBuildEvent="" 为我工作(MSBuild v4.0.30319)。
    • 它对我也不起作用(C++ 项目),但是 AndreiM 和 dtopham75 在下面发布的解决方案 (/p:PostBuildEventUseInBuild=false) 工作得很好。
    • 使用/p:PostBuildEvent="" 无效。它导致 MSBuild 尝试运行命令 "" (MS Build Tools 2019)
    【解决方案2】:

    根据项目类型,答案似乎不同。

    对于 C/C++ 项目 (.vcxproj),您可以使用 /p:PostBuildEventUseInBuild=false 在命令行上抑制 PostBuildEvent,正如 AndreiM 所建议的那样。

    (将 /p:PostBuildEvent 设置为空字符串不适用于 C++ 项目,我找不到任何其他方法来覆盖构建后命令)。

    对于 C# 项目 (.csproj),您可以在命令行中使用 /p:PostBuildEvent= 抑制 PostBuildEvent,正如大多数其他响应者所建议的那样。

    【讨论】:

    • 请注意,对于 C# 项目,如果您的 .csproj 文件有一个 Exec 标记且 Command 属性设置为 $(PostBuildEvent),则将 PostBuildEvent 设置为空字符串也会清除 Command 属性,这会导致构建错误。为了解决这个问题,我只是将其设置为“跳过构建后事件的回声”之类的良性内容,这很有效。
    【解决方案3】:

    你也可以使属性有条件

    <PreBuildEvent Condition="'$(BuildingInsideVisualStudio)' == '' Or '$(BuildingInsideVisualStudio)' == true"> ... </PreBuildEvent>
    

    【讨论】:

      【解决方案4】:

      我要做的是定义一个新的 .proj 文件,比如说 C:\Data\SupressBuildEvents.proj 它将包含:

      <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
          <Target Name="PostBuildEvent"/>
      
          <Target Name="PreBuildEvent" />
      </Project>
      

      然后您需要指定这些文件在 Microsoft.Common.targets 之后导入,您可以通过将众所周知的属性 CustomAfterMicrosoftCommonTargets 定义到该文件的路径来执行此操作。因此,让您的构建脚本位于名为 MyBuild.proj 的文件中,您可以将其调用为:

      msbuild MyBuild.proj /p:CustomAfterMicrosoftCommonTargets="C:\Data\SupressBuildEvents.proj
      "
      

      这将导致 MSBuild 在 Microsoft.Common.targets 文件被导入后导入您的文件,它将覆盖 PostBuildEvent 和 PreBuildEvent 目标并使它们不执行任何操作。

      现在,如果您的 MyBuild.proj 文件使用 MSBuild task 构建其他目标,那么您还应该将这个属性传递给它们,如下所示:

      <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
          <ItemGroup>
              <ProjectsToBuild Include=" FILL THIS IN "/>
          </ItemGroup>
      
          <Target Name="YourTarget">
              <MSBuild Projects="@(ProjectsToBuild)"
                       Properties="CustomAfterMicrosoftCommonTargets=$(CustomAfterMicrosoftCommonTargets)"/>
          </Target>
      
      </Project>
      

      这是必要的,因为父脚本上的设计属性不会传递给 MSBuild 任务执行的构建。

      【讨论】:

        【解决方案5】:

        我也玩了一点msbuild foo.vcxproj /p:PreBuildEvent= /p:PostBuildEvent=,但对我来说没用,可能是因为我使用的是自定义道具文件。

        我发现可以工作的是/p:PostBuildEventUseInBuild=false

        【讨论】:

          【解决方案6】:

          您还可以在 MSBuild 任务中设置属性:

          <MSBuild 
            Projects="$(MSBuildProjectDirectory)\YourProject.csproj" 
            Properties="Configuration=$(BuildConfiguration);BuildingFromBuildProjXml=true;PreBuildEvent=;PostBuildEvent=" 
            ContinueOnError="false" />
          

          【讨论】:

            【解决方案7】:

            在某些 C# 项目中,我需要 PostBuildEvent 在 Visual Studio 构建中工作,但在 MSBuild 和 TFS 构建中不起作用。为此,我在 VS 中添加了 PostBuildEvent。它在 .csproj 中设置以下代码:

              <PropertyGroup>
                <PostBuildEvent>*... my custom post build event ....*</PostBuildEvent>
              </PropertyGroup>
            

            之后,我将以下代码添加到 .csproj:

              <Target Name="BeforeBuild">
                  <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'false' Or '$(BuildingInsideVisualStudio)' != 'true'">
                    <PostBuildEvent></PostBuildEvent>
                  </PropertyGroup>
              </Target>
            

            此代码将 PostBuildEvent 设置为空,并且仅在 MSBuild 和 TFSBuild BeforeBuild 目标中发生。它简单,永久,不需要设置参数并且工作正常。

            【讨论】:

              【解决方案8】:
              <Target Name="PreBuild" BeforeTargets="PreBuildEvent" 
              Condition="'$(VisualStudioDir)' != ''">
              

              将此条件添加到项目 csproj 文件中 PreBuild 的目标是唯一对我有用的解决方案。我在尝试在 VSTS 中自动构建时遇到了这个问题,我想跳过项目 csproj 文件中定义的 PreBuild 事件。使用 Visual Studio 2017,一个 .NET Core 2.0 项目。

              我尝试了此处列出的 msbuild 命令行建议,但没有一个对我有用。

              【讨论】:

                【解决方案9】:

                默认情况下,当您导入 Microsoft.Common.targets 时,您会得到

                <PropertyGroup>
                    <BuildDependsOn>
                        BeforeBuild;
                        CoreBuild;
                        AfterBuild
                    </BuildDependsOn>
                </PropertyGroup>
                

                我认为您可以将其替换为

                <PropertyGroup>
                    <BuildDependsOn>
                        CoreBuild
                    </BuildDependsOn>
                </PropertyGroup>
                

                关闭这些构建前/构建后事件。 (不确定是否需要在导入之前或之后将其放入 .proj 文件中,或者是否需要修改 Microsoft.Common.targets 才能产生这样的效果。现在没有时间试验......)

                【讨论】:

                • 这不是你想做的。 BeforeBuild 和 AfterBuild 与构建前后的事件无关。
                猜你喜欢
                • 1970-01-01
                • 2017-12-02
                • 1970-01-01
                • 1970-01-01
                • 2010-11-21
                • 2010-12-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多