问题:ItemGroups数组无法根据排除属性中传递的值正确构建。

如果运行此脚本,它将创建一些示例文件,然后尝试根据Incluber/dublude属性创建一个名为thefiles的数组,问题是当排除属于硬编码或非常简单的属性以外的其他任何内容时,它会弄错它。

Target DynamiceXcludelist的错误选择了以下文件:
。 afolder test.cs;。 afolder test.txt

Target Hardcodedexcludelist的正确选择了这些文件:
。 afolder 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,但是当要排除的项目包含1个路径时,仍然存在问题(即 CommonFileExclusion 已经改变):

    <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>
有帮助吗?

解决方案

好的,我尝试了一点,我认为问题来自您使用代表多个值标量值的属性的事实。我建议批处理和转换(请参阅 http://scottlaw.knot.org/blog/?p=402http://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>

其他提示

在目标中 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>

理论上 ItemGroupCreateItem 是等效的,但我已经看到了这样的情况(动态情况) CreateItem 必须使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top