我有以下msbuild脚本:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="All">
<PropertyGroup>
...
</PropertyGroup>
<UsingTask AssemblyFile="$(GallioTaskPath)" TaskName="Gallio.MSBuildTasks.Gallio" />
<Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" />
<ItemGroup>
...
</ItemGroup>
<Target Name="CheckServerHostsItemGroup"
Condition="'$(NoServerHosts)' != True">
...
</Target>
<Target Name="RunServerHosts" DependsOnTargets="CheckServerHostsItemGroup"
Condition="'$(NoServerHosts)' != True">
...
</Target>
<Target Name="KillServerHosts" DependsOnTargets="CheckServerHostsItemGroup"
Condition="'$(NoServerHosts)' != True">
...
</Target>
<Target Name="KillServerHosts2"
Condition="'$(NoServerHosts)' != True">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="KillServerHosts" Properties="Configuration=$(Configuration)" />
</Target>
<Target Name="All" DependsOnTargets="Build;RunServerHosts;Test;KillServerHosts2">
<OnError ExecuteTargets="KillServerHosts2" />
</Target>
<Target Name="Test">
...
<Error Text="Tests execution failed with exit code $(ExitCode)" Condition="'$(ExitCode)' != 0" />
</Target>
<Target Name="CheckSolutionsItemGroup">
...
</Target>
<Target Name="Build" DependsOnTargets="CheckSolutionsItemGroup;KillServerHosts">
...
</Target>
<Target Name="Clean" DependsOnTargets="CheckSolutionsItemGroup;KillServerHosts">
...
</Target>
</Project>
我删除了目标的主体以节省空间,因为它们无关紧要。但是,如果有人认为他们是,我会包括他们。
无论如何,正如人们所看到的,有一个目标 - KillServerHosts
,我希望两次并且有充分的理由。在构建之前,为了确保没有锁定程序集,并且在测试完成后的另一时间完成“清理表”。
当然,尝试两次调用目标KillServerHosts
不起作用,MSBuild拒绝两次构建同一目标。所以,我试图通过调用目标KillServerHosts2
来作弊。问题在于它有时会起作用,有时却不起作用。
如果我从命令行运行KillServerHosts
目标,它总是会杀死相关的服务器主机,所以从这方面来说它可以正常工作。
有什么想法吗?
答案 0 :(得分:23)
按设计,MSBuild目标不会执行多次。您不应该将MSBuild目标视为方法或函数,因为MSBuild不是函数式编程语言。
如果要多次执行目标,可以使用MSBuild任务执行此操作,只需传入一组不同的属性即可。比如像这样的东西
<Target Name="SomeTarget">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="YourTarget" Properties="FakeProperty=one" />
<MSBuild Projects="$(MSBuildProjectFile)" Targets="YourTarget" Properties="FakeProperty=two" />
</Target>
注意:我实际上没有尝试过这样做,所以如果我拼错或记错了可能会出现语法问题,但你应该能够让它运转起来。