代码之家  ›  专栏  ›  技术社区  ›  Keith

msbuild itemgroup包含/排除模式问题

  •  8
  • Keith  · 技术社区  · 14 年前

    问题:没有根据exclude属性中传递的值正确生成itemgroups数组。

    如果运行这个脚本,它会创建一些示例文件,然后根据include/exclude属性尝试创建一个名为thefiles的数组,问题是当exclude不是硬编码的或是非常简单的属性时,它会出错。

    目标dynamicexcludelist错误地选择了这些文件:
    .\a文件夹\test.cs;.\a文件夹\test.txt

    目标的hardcodedExcludeList正确地选择这些文件:
    .\a文件夹\test.txt

    任何帮助都非常感谢,这让我抓狂。

    (注意其msbuild v4)

        <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Run">
    
          <Target Name="Run" >
            <CallTarget Targets="CreateSampleFiles" />
            <CallTarget Targets="DynamicExcludeList" />
            <CallTarget Targets="HardcodedExcludeList" />
          </Target>
    
          <Target Name="CreateSampleFiles" >
            <MakeDir Directories="AFolder" />
            <WriteLinesToFile Lines="Test" File="AFolder\test.cs" Overwrite="true" />
            <WriteLinesToFile Lines="Test" File="AFolder\test.txt" Overwrite="true" />
          </Target>
    
          <Target Name="DynamicExcludeList" >
    
            <PropertyGroup>
              <CommonFileExclusion>.\DIRECTORY_NAME_TOKEN\**\*.cs</CommonFileExclusion>
              <FinalExcludes>$(CommonFileExclusion.Replace('DIRECTORY_NAME_TOKEN', 'AFolder'))</FinalExcludes>
            </PropertyGroup>
    
            <Message Text="FinalExcludes: $(FinalExcludes)" />
            <ItemGroup>
              <TheFiles 
                Include=".\AFolder\**\*;" 
                Exclude="$(FinalExcludes)"
              />
            </ItemGroup>
            <Message Text="TheFiles: @(TheFiles)" />
    
          </Target>
    
          <Target Name="HardcodedExcludeList" >
    
            <PropertyGroup>
              <FinalExcludes>.\AFolder\**\*.cs</FinalExcludes>
            </PropertyGroup>
    
            <Message Text="FinalExcludes: $(FinalExcludes)" />
            <ItemGroup>
              <TheFilesWithHardcodedExcludes
                Include=".\AFolder\**\*;"
                Exclude="$(FinalExcludes)"
              />
            </ItemGroup>
            <Message Text="TheFilesWithHardcodedExcludes: @(TheFilesWithHardcodedExcludes)" />
    
          </Target>  
        </Project>
    

    这是输出,注意“thefiles”和“thefileswithhardcodedExcludes”之间的区别。

    PS C:\SVN\TrunkDeployment\TestMsBuild> msbuild .\Test.build.xml
    Microsoft (R) Build Engine Version 4.0.30319.1
    [Microsoft .NET Framework, Version 4.0.30319.1]
    Copyright (C) Microsoft Corporation 2007. All rights reserved.
    
    Build started 8/10/2010 2:30:42 PM.
    Project "C:\SVN\TrunkDeployment\TestMsBuild\Test.build.xml" on node 1 (default targets).
    DynamicExcludeList:
      FinalExcludes: .\AFolder\**\*.cs
      TheFiles: .\AFolder\test.cs;.\AFolder\test.txt
    HardcodedExcludeList:
      FinalExcludes: .\AFolder\**\*.cs
      TheFilesWithHardcodedExcludes: .\AFolder\test.txt
    Done Building Project "C:\SVN\TrunkDeployment\TestMsBuild\Test.build.xml" (default targets).
    
    
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:00.06
    

    编辑

    我已经更新了上面的脚本以使用createItem,但是当要排除的项列表包含多个路径(即 通用文件排除 改变了:

        <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Run">
    
          <Target Name="Run" >
            <CallTarget Targets="CreateSampleFiles" />
            <CallTarget Targets="DynamicExcludeList" />
            <CallTarget Targets="HardcodedExcludeList" />
          </Target>
    
          <Target Name="CreateSampleFiles" >
            <MakeDir Directories="AFolder" />
            <WriteLinesToFile Lines="Test" File="AFolder\test.cs" Overwrite="true" />
            <WriteLinesToFile Lines="Test" File="AFolder\test.txt" Overwrite="true" />
            <WriteLinesToFile Lines="Test" File="AFolder\test.vb" Overwrite="true" />
          </Target>
    
          <Target Name="DynamicExcludeList" >
    
            <PropertyGroup>
              <CommonFileExclusion>.\DIRECTORY_NAME_TOKEN\**\*.cs;.\DIRECTORY_NAME_TOKEN\**\*.vb;</CommonFileExclusion>
              <FinalExcludes>$(CommonFileExclusion.Replace('DIRECTORY_NAME_TOKEN', 'AFolder'))</FinalExcludes>
            </PropertyGroup>
    
            <Message Text="FinalExcludes: $(FinalExcludes)" />
            <CreateItem Include=".\AFolder\**\*;"
                         Exclude="$(FinalExcludes)">
              <Output TaskParameter="Include" ItemName="TheFiles"/>
            </CreateItem>
            <Message Text="TheFiles: @(TheFiles)" />
    
          </Target>
    
          <Target Name="HardcodedExcludeList" >
    
            <PropertyGroup>
              <FinalExcludes>.\AFolder\**\*.cs;.\AFolder\**\*.vb</FinalExcludes>
            </PropertyGroup>
    
            <Message Text="FinalExcludes: $(FinalExcludes)" />
            <CreateItem Include=".\AFolder\**\*;"
                         Exclude="$(FinalExcludes)">
              <Output TaskParameter="Include" ItemName="TheFilesWithHardcodedExcludes"/>
            </CreateItem>
            <Message Text="TheFilesWithHardcodedExcludes: @(TheFilesWithHardcodedExcludes)" />
    
          </Target>
        </Project>
    
    2 回复  |  直到 9 年前
        1
  •  15
  •   Benjamin Baumann    14 年前

    http://scottlaw.knot.org/blog/?p=402 http://msdn.microsoft.com/en-us/library/ms171476.aspx

    <Target Name="DynamicExcludeList" >
      <ItemGroup>
        <ExtensionsExcluded Include="cs;vb" />
      </ItemGroup>
    
      <CreateItem Include=".\AFolder\**\*"
              Exclude="@(ExtensionsExcluded->'.\AFolder\**\*.%(identity)')">
        <Output TaskParameter="Include" ItemName="TheFiles"/>
      </CreateItem>
      <Message Text="TheFiles: @(TheFiles)" />
    </Target>
    
        2
  •  2
  •   Julien Hoarau    14 年前

    DynamicExcludeList CreateItem ItemGroup

    <Target Name="DynamicExcludeList" >
    
      <PropertyGroup>
        <CommonFileExclusion>.\DIRECTORY_NAME_TOKEN\**\*.cs</CommonFileExclusion>
        <FinalExcludes>$(CommonFileExclusion.Replace('DIRECTORY_NAME_TOKEN', 'AFolder'))</FinalExcludes>
      </PropertyGroup>
    
      <Message Text="FinalExcludes: $(FinalExcludes)" />
    
      <CreateItem Include=".\AFolder\**\*;"
                  Exclude="$(FinalExcludes)">
        <Output TaskParameter="Include" ItemName="TheFiles"/>
      </CreateItem>
    
      <Message Text="TheFiles: @(TheFiles)" />
    </Target>
    

    推荐文章