我一直在努力让我的TFS版本中的任务更通用,我尝试做的一件事就是根据使用任务的构建将一些文件复制到不同的目录。我玩弄了使用属性的想法,但我想不出干净利落的方法,所以我尝试使用项目元数据,因为我已经能够在同一目标文件中的另一个地方这样做我正在努力,只是这一次,我想使用属性。
这就是我想要做的事情:
<ItemGroup>
<DestinationParent Include="$(DeploymentPath)">
<DestinationParentPath>$(DeploymentPath)</QuartzParentPath>
</DestinationParent>
</ItemGroup>
稍后在构建中,我尝试通过引用项元数据将一些文件复制到目标文件夹:
<Copy SourceFiles="@(FilesToCopy)" DestinationFiles="@(FilesToCopy->'%(DestinationParentPath)\Destination\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" ></Copy>
不幸的是,在构建运行之后,我的BuildLog显示以下内容:
Copying file from "$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\<File being copied>" to "\Destination\<File being copied>".
无论出于何种原因,%(DestinationParentPath)已扩展为空字符串。使用%(DestinationParent.DestinationParentPath)产生错误,告诉我我应该只使用%(DestinationParentPath)。 $(DeploymentPath)在构建中的其他几个位置按预期扩展为正确的字符串。
混淆的另一个原因是使用%(ConfigurationToBuild.FlavorToBuild)产生了正确的值,即Test,如下所示:
编辑:这是在根节点Project下定义的,而具有DestinationParentPath的ItemGroup是在Target节点下定义的。这也有所作为吗?
<ItemGroup>
<ConfigurationToBuild Include="Test|Any CPU">
<FlavorToBuild>Test</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</ConfigurationToBuild>
</ItemGroup>
当你只对项目元数据中的字符串感兴趣时,看起来并不像Include属性,因为我很确定“Test | Any CPU”不会引用任何实际文件。
再一次,为什么%(DestinationParentPath)扩展为空字符串?
编辑:我忘了提到我还尝试对DestinationParentPath的实际路径进行硬编码,但这仍然导致%(DestinationParentPath)扩展为空字符串。
答案 0 :(得分:1)
编辑:这是在根节点Project下定义的,而具有DestinationParentPath的ItemGroup是在Target节点下定义的。这也有所作为吗?
是的,它有所不同。在Target中定义ItemGroup的能力是msbuild 3.5的新功能。尽管看起来是声明性的,它实际上是在运行时执行的,就像你调用了旧式的CreateItem / CreateProperty任务一样。仅这一点就会导致潜在问题:您需要考虑何时(首先)调用包含任务。 Order of operations is not always obvious to the naked eye。使用%(DestinationParentPath)依赖于创建它的任务的任务可能是明智的,即使没有“逻辑”依赖。
此外,还有历史悠久的msbuild范围怪癖/错误。 Dynamically created properties & items are not visible to "sibling" tasks。另外,items updated in nested builds aren't always bubbled up。
查看链接中的变通方法,你应该能够找到适合你的东西,即使它很蹩脚。