Search code examples
c#visual-studiovisual-studio-2017post-build-eventbuild-events

How to suppress initial post-build event error in Visual Studio 2017 (C#)?


I have a C# solution in Visual Studio 2017. I also have a batch script called foobar.bat that contains the following code:

echo foobar : error 1: This is a test error.           

My goal is to get only the test error message above to appear in Visual Studio's Error List when I build a particular project and for the build to stop when it appears. So I put [path to script]\foobar.bat in the project's post-build event command line and then build. Now I'm getting two error messages in the Visual Studio Error List:

  1. The command "[path to script]\foobar.bat" exited with code -1.
  2. This is a test error.

In this case, seeing that first error message that just prints out the contents of my post-build event isn't helpful. I want to suppress this initial error so that only my custom error messages show up in the Error List (or at least change it to say something more useful).

Here's what I've tried:

  • Adding 2>nul to the end of my batch script has no effect.
  • Adding 1>nul to the end of my batch script suppresses both errors, which isn't what I want.
  • Adding &set errorlevel=0 to the end of my batch script has no effect.
  • Adding the line exit 0 to the end of my batch script has no effect.
  • Adding the following to the end of my .csproj file (per this article) suppresses the first error, but makes it so the build no longer fails:
<Target
    Name="PostBuildEvent"
    Condition="'$(PostBuildEvent)'!=''"
    DependsOnTargets="$(PostBuildEventDependsOn)">
    <Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" IgnoreExitCode="true" />
</Target>

The last option almost gets me what I want. However, in spite of there being an error message, the Error List doesn't pop up and the build does not fail. It appears as though anything that would cause the initial error message to not appear will also cause the build to no longer fail. Is that the case? Or is there some way I can get the build to fail without showing that initial error message?


Solution

  • What you can do is use an exec and an error task together.

    You need to edit the .csproj file and add these tasks after your the Target PostBuildEvent from your last bullet point above.

    This solution works by getting the ExitCode and Output of your exec task and using them to trigger the error task which will then stop the build and log the message.
    The Exec task needs three parameters:

    • IgnoreStandardErrorWarningFormat and IgnoreExitCode prevent the error from being logged at this step
    • ConsoleToMsBuild parameter is required to get the output (spelled ConsoleToMSBuild in VS 2017).

    So the tasks look like this:

      <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="$(PostBuildEvent)" IgnoreStandardErrorWarningFormat="true" IgnoreExitCode="true" ConsoleToMsBuild="true">
          <Output TaskParameter="ConsoleOutput" PropertyName="OutputMessage" />
          <Output TaskParameter="ExitCode" PropertyName="ExitCode" />
        </Exec>
        <Error Text="$(OutputMessage)" Condition="$(ExitCode) == 10" />
        <!-- <Error Text="(optional text) : $(OutputMessage)" Condition="$(ExitCode) == 11" />
        <Error Text="(optional text) : $(OutputMessage)" Condition="$(ExitCode) == 12" /> -->
      </Target>
    
    

    And edit the file foobar.bat:

    echo foobar : error 1: This is a test error.
    exit /b 10 <-- /b parameter needed if used in a .bat file
    

    The important part is the exit that will set the code we want to use afterwards.

    You can have more than one Error task do to more conditional logging or just use the output as is.