如何使用MSBuild ItemGroups在“循环”中执行EXEC任务?

52

如何在MSBuild ItemGroups中对“EXEC”任务执行“循环”操作?

而不是像下面这样一遍又一遍地重复此命令:

    <Exec ContinueOnError="false" Command="sqlcmd -S $(ServerName) $(SqlServerUser) -d $(DbName) -v TableName=%22account%22 -i data\add_sql_cache.sql -b" />
    <Exec ContinueOnError="false" Command="sqlcmd -S $(ServerName) $(SqlServerUser) -d $(DbName) -v TableName=%22services%22 -i data\add_sql_cache.sql -b" />
    <Exec ContinueOnError="false" Command="sqlcmd -S $(ServerName) $(SqlServerUser) -d $(DbName) -v TableName=%22servicesGroup%22 -i data\add_sql_cache.sql -b" />
    <Exec ContinueOnError="false" Command="sqlcmd -S $(ServerName) $(SqlServerUser) -d $(DbName) -v TableName=%22servicesCategory%22 -i data\add_sql_cache.sql -b" />

我更想定义一个ItemGroup,然后执行一个“循环”。 我已经定义好了ItemGroup:

<ItemGroup>
    <CachedTables Include="account" />
    <CachedTables Include="services" />
    <CachedTables Include="servicesGroup" />
    <CachedTables Include="servicesCategory" />

但由于MSBuild令人难以理解的语法,我不知道如何在循环中执行带有上述ItemGroup作为输入的Exec任务。


2
我的回答被删除了,但是我想声明一下,自从我写这个问题以来的经验让我非常坚信这是一个不好的想法:你应该使用像 Psake 或 gulp 这样的工具来完成这样的事情。 - Josh Kodroff
2个回答

56

有两种方法可以实现这个,都是“批处理”的形式。

你可以对目标进行批处理并执行Exec和其他操作,

<Target Name="ExecMany"
  Outputs="%(CachedTables.Identity)">
  <Exec
    Command="sqlcmd -S ... TableName=%22%(CachedTables.Identity)%22 -i ..."
    />
  <SomeOtherTask ThatUses="%(CachedTables.Identity)" />
</Target>
另一个方法是对Exec任务使用任务批处理,与之类似。
<Target Name="ExecMany">
  <Exec
    Command="sqlcmd -S ... TableName=%22%(CachedTables.Identity)%22 -i ..."
    />
  <SomeOtherTask ThatUses="%(CachedTables.Identity)" />
</Target>

它们的区别在于操作方式。第一种情况下,由于批处理是针对整个目标的(通过Outputs属性实现),因此Exec任务和SomeOtherTask将对组中的每个项执行。换句话说,

Exec with "account"
SomeOtherTask with "account"
Exec with "services"
SomeOtherTask with "services"
...
第二种选择,单独批处理每个任务,将产生以下序列:
Exec with "account"
Exec with "services"
...
SomeOtherTask with "account"
SomeOtherTask with "services"
...

6
以下是我找到的与Brian的回答相关的MSDN链接:MSBuild 批处理转换项元数据。请参考。 - Shawn Hoover

41

如果我理解问题正确,它可以更简单地完成。以下示例使用<Exec/>来逐个输出<ItemGroup/>中的每个项目。

  <ItemGroup>
    <MySpecialItem Include="one" />
    <MySpecialItem Include="two" />
    <MySpecialItem Include="three" />
  </ItemGroup>    

  <Target Name="MyTarget">
    <Exec Command="echo %(MySpecialItem.Identity)"/>
  </Target>

当你不知道MySpecialItem是什么时,你会怎么做?例如,MySpecialItem可能是多行变量的内容。 - kayleeFrye_onDeck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接