如何在var的定义中引用ItemGroup Identity



我有一个如下的目标:它需要用新内容替换文件的内容。我有多个文件,我与ItemGroup匹配。我想不出一个方法让它工作。

这是我的目标定义。

<ItemGroup>
<PRSetting Include="$(settings_root)**settings_config_*.xml">
<NewContent>$([System.IO.File]::ReadAllText('%(Identity)')).Replace('[config.version]', '$(PR_Version)'))</NewContent>
</PRSetting>
</ItemGroup>
<Target Name="PrepSettings" Inputs="@(PRSetting)" 
Outputs="@(PRSetting->'$out$Filename.xml')" >
<Message Text="%(PRSetting.Identity) new contents:" />
<Message Text="%(PRSetting.NewContent)"/>
</Target>

我希望我正确地解释了我正在努力做的事情。当构建目标时,我得到一个错误,即File::ReadFile()的路径不能是空字符串。我正在使用VS 2019。这项工作还在进行中。我还没有弄清楚如何在目标文件中保存新内容。


我有Itemgroup在外面。我更新了这个问题。它在外部的原因是目标输入参数需要它。

尝试以下操作,看看是否有效:

<Target Name="PrepSettings">
<ItemGroup>
<PRSetting Include="$(settings_root)**settings_config_*.xml" />
<PRSetting>
<NewContent Condition="%(Identity) != ''">$([System.IO.File]::ReadAllText('%(Identity)')).Replace('[config.version]', '$(PR_Version)'))</NewContent>
</PRSetting>
</ItemGroup>
<Message Text="@(PRSetting.Identity) new contents:" />
<Message Text="%(PRSetting.NewContent)"/>
</Target>

有两个变化:

  1. 似乎有一个问题与Include,不使用现有的ItemGroup和元数据是自我引用。因此,设置PRSetting分为两部分。
    • 首先用Include建立PRSetting
    • 第二,重新添加NewContent元数据项。
  2. NewContent元数据上添加Condition="%(Identity) != ''"

我目前还不能完全测试你的确切场景,但我测试了一个模拟。

下面是我的测试模拟:

<Target Name="PrepSettings">
<ItemGroup>
<PRSetting Include="1;4;2;3"/>
<PRSetting>
<NewContent Condition="%(Identity) != ''">$([MSBuild]::Add('%(Identity)', '1'))</NewContent>
</PRSetting>
</ItemGroup>
<Message Text="PRSetting is @(PRSetting->'(%(Identity),%(NewContent))');" />
</Target>

输出为

PrepSettings:
PRSetting is (1,2);(4,5);(2,3);(3,4);

关于将ItemGroup移出目标的代码更改:

  • ItemGroup拆分为编写的技术将不起作用,但如果您使用VS2017或更高版本并使用。net Core/。. NET 5+可以使用Update.
  • 如问题所示,Outputs属性有语法错误。我认为Outputs="@(PRSetting->'$(OutputPath)%(Filename).xml')"(或接近)是有意的。
  • 如问题所示,Outputs属性永远不会满足,因为PrepSettings不创建文件。我认为PrepSettings如所示是不完整的。