visual studio – Why are the C# pre-build and post-build events not called if I import a custom target with my own build target in it?


Your custom Build target is overriding the project system provided Build target.

As of the time of writing this answer, the project system Build is defined as follows:

  <!--
    ============================================================
                                        Build

    The main build entry point.
    ============================================================
    -->
  <PropertyGroup>
    <BuildDependsOn>
      BeforeBuild;
      CoreBuild;
      AfterBuild
    </BuildDependsOn>
  </PropertyGroup>

  <Target
      Name="Build"
      Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
      DependsOnTargets="$(BuildDependsOn)"
      Returns="@(TargetPathWithTargetPlatformMoniker)" />

The definition of the CoreBuild target is where the PreBuildEvent and PostBuildEvent targets are introduced to the target chain.

As of the time of writing this answer, CoreBuild is defined as follows:

  <!--
    ============================================================
                                        CoreBuild

    The core build step calls each of the build targets.
    ============================================================
    -->
  <PropertyGroup>
    <CoreBuildDependsOn>
      BuildOnlySettings;
      PrepareForBuild;
      PreBuildEvent;
      ResolveReferences;
      PrepareResources;
      ResolveKeySource;
      Compile;
      ExportWindowsMDFile;
      UnmanagedUnregistration;
      GenerateSerializationAssemblies;
      CreateSatelliteAssemblies;
      GenerateManifests;
      GetTargetPath;
      PrepareForRun;
      UnmanagedRegistration;
      IncrementalClean;
      PostBuildEvent
    </CoreBuildDependsOn>
  </PropertyGroup>

  <Target
      Name="CoreBuild"
      DependsOnTargets="$(CoreBuildDependsOn)">

    <OnError ExecuteTargets="_TimeStampAfterCompile;PostBuildEvent" Condition="'$(RunPostBuildEvent)'=='Always' or '$(RunPostBuildEvent)'=='OnOutputUpdated'"/>
    <OnError ExecuteTargets="_CleanRecordFileWrites"/>

  </Target>

Because you override Build and your override doesn’t have DependsOnTargets="$(BuildDependsOn)", CoreBuild is not in the target chain. Then because CoreBuild is not in the target chain, its dependencies, including PreBuildEvent and PostBuildEvent, are not in the target chain.

You could change your custom build to something like the following which sets a target chain that includes PreBuildEvent and PostBuildEvent.

    <Target Name="Build" DependsOnTargets="PreBuildEvent;CustomBuild;PostBuildEvent"/>
    <Target Name="CustomBuild">
        <Message Text="Custom Build started" Importance="high"/>
    </Target>

If what you actually need is a “utility” project that doesn’t actually build, see the “Microsoft.Build.NoTargets” project SDK.

Leave a Reply

Your email address will not be published. Required fields are marked *