问题:未根据exclude属性中传递的值正确构建ItemGroups数组。
如果你运行这个脚本它会创建一些示例文件,然后尝试根据Include / Exclude属性创建一个名为TheFiles的数组,问题是当Exclude是硬编码以外的任何东西时,或者是一个非常简单的属性它是错误的。
目标DynamicExcludeList错误地选择了这些文件:
\ AFolder \ test.cs中; \ AFolder \ test.txt的
目标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
EDITS
我已更新上述脚本以使用CreateItem,但是当要排除的项目列表包含多个路径(即 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>
答案 0 :(得分:15)
好的,我尝试了一下,我认为问题来自于您使用表示多个值的SCALAR值的属性。我建议批处理和转换(请参阅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>
答案 1 :(得分:2)
在目标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>
从理论上讲,ItemGroup
和CreateItem
是等价的,但我必须使用CreateItem
时遇到过类似情况(动态情况)。