在MSBuild中交叉连接项目组

在MSBuild中交叉连接项目组,msbuild,itemgroup,Msbuild,Itemgroup,考虑到这样的情况 DB1 数据库 DB2 登录中 我希望输出是这样的。。(给定两个文件one.config和two.config) (顺序并不重要,只是两个项目组的完全笛卡尔积)有一种方法可以做到这一点,只需对现有示例代码进行最小的更改。您可以从ConfigFilesitems和DatabaseConfigitems中选择一个新的“组合”项,然后输出该“组合”项 要组合元数据,请与为每个DatabaseConfig项运行一次的批处理目标一起使用。然后,您可以调用另一个目标来输出组合的元数据,

考虑到这样的情况


DB1
数据库
DB2
登录中
我希望输出是这样的。。(给定两个文件one.config和two.config)


(顺序并不重要,只是两个项目组的完全笛卡尔积)

有一种方法可以做到这一点,只需对现有示例代码进行最小的更改。您可以从
ConfigFiles
items和
DatabaseConfig
items中选择一个新的“组合”项,然后输出该“组合”项

要组合元数据,请与为每个
DatabaseConfig
项运行一次的批处理目标一起使用。然后,您可以调用另一个目标来输出组合的元数据,以获得您描述的输出。请查看我对您的示例代码的扩展,以了解如何实现这一切:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
    <ConfigFiles Include="*.config" />

    <DatabaseConfig Include="ABC">
      <Database>DB1</Database>
      <CsString>Database</CsString>
    </DatabaseConfig>

    <DatabaseConfig Include="DEF">
      <Database>DB2</Database>
      <CsString>Logging</CsString>
    </DatabaseConfig>
  </ItemGroup>

  <Target Name="test" DependsOnTargets="test_setup;test_output" >
    <!-- Logic here runs after targets listed in "DependsOnTargets". -->
  </Target>

  <!-- This will run once for each "DatabaseConfig" item. -->
  <Target Name="test_setup" Outputs="%(DatabaseConfig.Identity)">
    <PropertyGroup>
      <!-- Specify the Database for the current DatabaseConfig item -->
      <CurrentDb>%(DatabaseConfig.Database)</CurrentDb>
    </PropertyGroup>
    <ItemGroup>
      <!-- Add a new CombinedOutput item with each run, combining metadata. -->
      <CombinedOutput Include=" %(ConfigFiles.FileName)%(ConfigFiles.Extension) $(CurrentDb) " />
    </ItemGroup>
  </Target>

  <Target Name="test_output">
    <!-- Output the combined metadata from the CombinedOutput items -->
    <Message Text=" %(CombinedOutput.Identity) " />
  </Target>

</Project>

这似乎是一个整洁的解决方案:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <ConfigFiles Include="*.config" />

        <DatabaseConfig Include="ABC">
            <Database>DB1</Database>
            <CsString>Database</CsString>
        </DatabaseConfig>

        <DatabaseConfig Include="DEF">
            <Database>DB2</Database>
            <CsString>Logging</CsString>
        </DatabaseConfig>
    </ItemGroup>

    <Target Name="test" >
        <ItemGroup>
            <Combined Include="@(DatabaseConfig)">
                <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
            </Combined> 
        </ItemGroup>
    <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
    </Target> 
</Project>

DB1
数据库
DB2
登录中
%(ConfigFiles.Identity)

这将不会以您想要的方式组合项目元数据或生成所需的输出。这将只在一行上输出
DB1
,在另一行上输出
DB2
。我建议的答案允许在组合元数据时具有灵活性,并将生成您要求的输出。啊,我看到了在本地尝试时出现的问题:当我尝试时,我认为指向示例配置的路径是错误的。您的提供了配置的完整路径,而不仅仅是配置文件名/扩展名。哈哈哈,您的答案毕竟是简明的。;-)我应该有更明确的,我需要这两个变量是分开的。这条消息只是为了测试,实际变量将在XmlUpdate步骤中使用。嗯,是的,事先知道这一点会很好。;-)我的建议回答了您最初的标准,但并不侧重于将这些变量分开。
one.config DB1
two.config DB1
one.config DB2
two.config DB2
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <ConfigFiles Include="*.config" />

        <DatabaseConfig Include="ABC">
            <Database>DB1</Database>
            <CsString>Database</CsString>
        </DatabaseConfig>

        <DatabaseConfig Include="DEF">
            <Database>DB2</Database>
            <CsString>Logging</CsString>
        </DatabaseConfig>
    </ItemGroup>

    <Target Name="test" >
        <ItemGroup>
            <Combined Include="@(DatabaseConfig)">
                <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
            </Combined> 
        </ItemGroup>
    <Message Text=" %(Combined.ConfigFile) %(Combined.Database) " />
    </Target> 
</Project>