如何为批处理任务的每次执行获取MSBuild输出参数?

如何为批处理任务的每次执行获取MSBuild输出参数?,msbuild,Msbuild,我有一个MSBuild目标,它在多个项目上运行Exec任务。我如何获得他们每个人的退出代码 我可以使用此选项获取所有退出代码,并且仅当输入文件自上次运行(即增量构建)以来发生更改时才运行: 因此,这会打印返回的所有不同的退出代码,但它不会将它们与输入项相关联,因此我不知道哪些输入已成功处理,哪些未成功处理。实现这一点的最简单方法是越过目标,而不是任务本身。有效地“将循环向上移动一个级别”,从(伪代码): 到 如果项目表示生成输出的文件,这很简单,您应该在输入属性中批处理(并定义输出以获得正确的增

我有一个MSBuild目标,它在多个项目上运行Exec任务。我如何获得他们每个人的退出代码

我可以使用此选项获取所有退出代码,并且仅当输入文件自上次运行(即增量构建)以来发生更改时才运行:


因此,这会打印返回的所有不同的退出代码,但它不会将它们与输入项相关联,因此我不知道哪些输入已成功处理,哪些未成功处理。

实现这一点的最简单方法是越过目标,而不是任务本身。有效地“将循环向上移动一个级别”,从(伪代码):

如果项目表示生成输出的文件,这很简单,您应该在
输入
属性中批处理(并定义
输出
以获得正确的增量行为)

对于您给出的示例,这有点令人困惑,因为目标没有生成一组输出文件。这意味着您必须误用目标的
输出
属性来获得批处理行为。你可以做:

<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>

这种方法之所以有效,是因为在批处理中,使用
@(ItemName)
访问的项目只包含适合该批处理的结果。如果您仔细确保每个批次仅为一项,则可以将输出与输入关联起来。

例如,这正是您想要的(只需使用readline而不是exexe获取输出,但原理相同),因此基本上只需添加
outputs=“%(TestItem.Identity)”
?这是个好把戏,谢谢!唯一的问题是,我的实际目标已经设置了输出以启用增量生成,因此我想我必须将Exec任务放入子目标中,并使用MSBuild任务调用该子目标。在这种情况下,我不建议使用MSBuild任务,因为要能够多次调用它,您必须更改全局属性,这是危险的。不过,你应该能够避免它。你能更新问题使目标看起来更像你的真实目标吗?我打赌有一种方法可以让它一起工作。好的,我已经编辑了这个问题。基本上,我希望只在输出早于输入时运行Exec任务来支持增量构建。我在目标的末尾编写了一行文本文件,作为“输出”。您几乎可以免费获得该行为—请参阅。皱纹是您的
@(其他输入)
,它打破了输入和输出之间的1:1关系。但我不太确定这与编辑后的问题有什么关系——你所做的
Exec
ing是最新的检查吗?不,Exec是真正的构建。实际上,它发出咕噜声@(其他输入)是grunt构建的所有输入。当然,grunt构建有真实的输出文件,但由于它们有点难以跟踪,我选择了更简单的选项,即在构建运行时“触摸”一个特殊文件并检查该文件。
Ran ItemTest. Exit code=0
Ran ItemTest. Exit code=1
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)
    }
}
<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).