【发布时间】:2018-01-05 03:30:57
【问题描述】:
我想运行一个 MSBuild 任务(对可执行文件/dll 进行签名),但前提是输出 exe/dll 已更改。如果没有任何源文件更改导致重新编译 exe/dll,那么我不希望任务运行。
尽管花了几个小时尝试不同的事情,但我无法弄清楚如何让我的目标任务仅在项目已编译且输出文件已更改的情况下运行(换句话说,我认为没有跳过 CoreCompile 目标)。
【问题讨论】:
标签: msbuild
我想运行一个 MSBuild 任务(对可执行文件/dll 进行签名),但前提是输出 exe/dll 已更改。如果没有任何源文件更改导致重新编译 exe/dll,那么我不希望任务运行。
尽管花了几个小时尝试不同的事情,但我无法弄清楚如何让我的目标任务仅在项目已编译且输出文件已更改的情况下运行(换句话说,我认为没有跳过 CoreCompile 目标)。
【问题讨论】:
标签: msbuild
你可以这样做:
<PropertyGroup>
<TargetsTriggeredByCompilation>DoStuffWithNewlyCompiledAssembly</TargetsTriggeredByCompilation>
</PropertyGroup>
之所以可行,是因为 Microsoft 的某个聪明人在 Microsoft.[CSharp|VisualBasic][.Core].targets 中的 CoreCompile 目标末尾添加了以下行(文件名取决于语言和 MSBuild/Visual Studio 版本)。
<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>
因此,如果您在 TargetsTriggeredByCompilation 属性中指定目标名称,则如果 CoreCompile 运行,您的目标将运行-- 如果跳过 CoreCompile,您的目标将不会运行(例如,因为输出程序集已经启动-迄今为止关于代码)。
【讨论】:
应该和this answer一样,使用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)'!=''" />
【讨论】: