8
votes

I want to run an MSBuild Task (which signs an executable/dll) but only when the output exe/dll has changed. If none of the source files have changed causing a recompile of the exe/dll then I don't want the task to run.

Despite spending several hours trying different things out I cannot work out how to get my target task to only run if the project has been compiled where the output files have changed (in other words the CoreCompile target was not skipped I think).

2

2 Answers

4
votes

You can just do this:

<PropertyGroup>
  <TargetsTriggeredByCompilation>DoStuffWithNewlyCompiledAssembly</TargetsTriggeredByCompilation>
</PropertyGroup>

This works because someone smart at Microsoft added the following line at the end of the CoreCompile target in Microsoft.[CSharp|VisualBasic][.Core].targets (the file name depends on the language and MSBuild/Visual Studio version).

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>

So if you specify a target name in the TargetsTriggeredByCompilation property, your target will run if CoreCompile runs-- and your target will not run if CoreCompile is skipped (e.g. because the output assembly is already up-to-date with respect to the code).

2
votes

Should be the same as this answer, using the TargetOutputs parameter::

<MSBuild Projects="File.sln" >
   <Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects" />
</MSBuild>
<Message Text="Assemblies built: @(AssembliesBuiltByChildProjects)" /> <!-- just for debug -->
<CallTarget Targets="SignExe" Condition="'@(AssembliesBuiltByChildProjects)'!=''" />