我有一个MSBuild目标,它在几个项目上运行Exec任务。如何获取每个退出代码?
我可以使用它来获取所有退出代码,并且仅在输入文件自上次运行后发生更改时运行(即增量构建):
<ItemGroup>
<TestItem Include="MyFile1" />
<TestItem Include="MyFile2" />
<TestItem Include="MyFile10" />
</ItemGroup>
<Target Name="PrepareItemTest">
<ItemGroup>
<TestItem>
<!-- The timestamp of the "done file" is used below to detect if this target has been run since the inputs have been modified. -->
<DoneFilePath>%(TestItem.RelativeDir)%(TestItem.Filename).done/DoneFilePath>
</TestItem>
</ItemGroup>
</Target>
<Target Name="ItemTest"
DependsOnTargets="PrepareItemTest"
Inputs="@(TestItem);@(OtherInputs)"
Outputs="%(TestItem.DoneFilePath)">
<Exec Command="ECHO Running on %(TestItem.Identity) |findstr 1" IgnoreExitCode="true">
<Output TaskParameter="ExitCode" PropertyName="TestExitCode"/>
</Exec>
<Error Condition=" '$(TestExitCode)' != '0' " Text="Error $TestExitCode" />
<WriteLinesToFile Condition=" '$(TestExitCode)' == '0' " File="%(TestItem.DoneFilePath)" Lines="Ran successfully on %(TestItem.Filename)%(TestItem.Extension)" />
</Target>
输出:
Ran ItemTest. Exit code=0
Ran ItemTest. Exit code=1
因此,这会打印返回的所有不同退出代码,但它不会将它们与输入项相关联,因此我不知道哪些输入已成功处理,哪些输入未成功处理。
答案 0 :(得分:2)
实现此目的的最简单方法是batch而非目标而不是任务本身。这实际上有效地将循环从(伪代码)移动到了一个级别:
target PrepareItemTest {
foreach item in TestItem {
TestExitCode.append(exec().result))
}
warn("exit codes: " + TestExitCode)
}
到
target PrepareItemTest {
foreach item in TestItem {
TestExitCode.append(exec().result))
warn("exit code: " item + " " + TestExitCode)
}
}
如果项目代表生成输出的文件,则这很简单,您应该在Inputs
属性中进行批处理(并定义Outputs
以获得正确的增量行为)。
对于您给出的示例,它有点令人困惑,因为目标不会产生一组输出文件。这意味着您必须滥用目标的Outputs
属性才能获得批处理行为。你可以这样做:
<Target Name="ItemTest" Outputs="%(TestItem.Identity)">
<Exec Command="ECHO Running on @(TestItem->'%(Identity)') |findstr 1" IgnoreExitCode="true">
<Output TaskParameter="ExitCode" PropertyName="TestExitCode"/>
</Exec>
<Warning Text="Ran ItemTest for @(TestItem). Exit code=$(TestExitCode)" />
</Target>
哪个产生
Project "D:\work\batch-over-target.proj" on node 1 (default targets).
ItemTest:
ECHO Running on MyItem1 |findstr 1
Running on MyItem1
D:\work\batch-over-target.proj(14,5): warning : Ran ItemTest for MyItem1. Exit code=0
ItemTest:
ECHO Running on MyItem2 |findstr 1
The command "ECHO Running on MyItem2 |findstr 1" exited with code 1.
D:\work\batch-over-target.proj(14,5): warning : Ran ItemTest for MyItem2. Exit code=1
ItemTest:
ECHO Running on MyItem10 |findstr 1
Running on MyItem10
D:\work\batch-over-target.proj(14,5): warning : Ran ItemTest for MyItem10. Exit code=0
Done Building Project "D:\work\batch-over-target.proj" (default targets).
这样做的原因是,在批处理中,使用@(ItemName)
访问的项目仅包含适合批处理的结果。如果您小心确保每个批次只有一个项目,则可以将输出与输入相关联。