Search code examples
c#msbuildvisual-studio-2017csprojmsbuild-target

MsBuild PostBuild targets


I have added an AfterBuild target to a Visual Studio project, which is part of a solution containing multiple Visual Studio projects.

Example Solution setup

Example.sln

  • ExampleProj.csproj

  • ExampleProj.Test.csproj

Example of Target:

  <Target Name="PostBuildScript" AfterTargets="AfterBuild" Condition="'$(Configuration)' == 'Release'">
    <PropertyGroup>
      <BuildCommand>"SomeApplication.exe")</BuildCommand>
    </PropertyGroup>
    <Exec Command="$(BuildCommand)" ConsoleToMSBuild="true" LogStandardErrorAsError="true" WorkingDirectory="$(ProjectDir)" />
  </Target>

I would like this target to execute only after all of the Visual Studio projects in the solution have been built.

Is there a way to achieve this.

Note: I need the behaviour to be the same when using dotnet build as well as the build command in Visual Studio.


Solution

  • I would like this target to execute only after all of the Visual Studio projects in the solution have been built

    According to the document MSBuild Extending The Solution Build, you could create a MSBuild project files named after.<SolutionName>.sln.targets in the same folder as your solution.

    As test, I added this to my After.Solution.sln.targets file (Use a banana instead of SomeApplication.exe), and set this file in the same folder as my solution file .sln:

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
      <Target Name="PostBuildScript" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
        <Message Text="*** BEGIN BANANA ***" Importance="high" />
        <Message Text=" _                                          " Importance="high" />
        <Message Text="//\                                         " Importance="high" />
        <Message Text="V  \                                        " Importance="high" />
        <Message Text=" \  \_                                      " Importance="high" />
        <Message Text="  \,'.`-.                                   " Importance="high" />
        <Message Text="   |\ `. `.                                 " Importance="high" />
        <Message Text="   ( \  `. `-.                        _,.-:\" Importance="high" />
        <Message Text="    \ \   `.  `-._             __..--' ,-';/" Importance="high" />
        <Message Text="     \ `.   `-.   `-..___..---'   _.--' ,'/ " Importance="high" />
        <Message Text="      `. `.    `-._        __..--'    ,' /  " Importance="high" />
        <Message Text="        `. `-_     ``--..''       _.-' ,'   " Importance="high" />
        <Message Text="          `-_ `-.___        __,--'   ,'     " Importance="high" />
        <Message Text="             `-.__  `----'''    __.-'       " Importance="high" />
        <Message Text="                  `--..____..--'            " Importance="high" />
        <Message Text="*** END BANANA ***"  Importance="high" />
      </Target>
    
    </Project>
    

    Then I build it with dotnet build command:

    dotnet build "xxxx\TestSolutionTarget.sln" --configuration Release --verbosity n
    

    enter image description here

    This target execute after all of the Visual Studio projects in the solution have been built.

    Alternatively, you could also create separate empty project, referencing subset of all the projects and adding this target to the empty project.

    Hope this helps.