在Tar​​get块之外使用MSBuild PropertyGroup

时间:2012-12-24 11:29:53

标签: msbuild

我有一个项目文件集合:

<ItemGroup>
  <ApplicationToDeploy
    Include="Frontend.WebSite.csproj;11.WebServices.csproj;22.WebServices.csproj"/>
  <ApplicationToDeploy
    Include="33.WebServices.csproj;44.WebServices.csproj;Workflow55Svc.csproj"/>
</ItemGroup>

我正在尝试收集这些项目的.config文件:

<Target Name="111">
  <PropertyGroup>
    <Cfgs>@(ApplicationToDeploy->'%(RootDir)%(Directory)*.config')</Cfgs>
  </PropertyGroup>

  <ItemGroup>
    <InputConfigs Include="$(Cfgs)" />
  </ItemGroup>

  <Message Text="Cfgs: @(InputConfigs)"/>
</Target>

目标块中,一切正常(我看到Web.Configs,App.Configs,Log4net.Configs等集合):

Cfgs: C:\Sources\WebServices\11\WebServices\11.WebServices\Web.config;C:\Sources\WebServices\22\WebServices\22.WebServices\web.log4net.config;C:\Sources\WebServices\33\WebServices\33.WebServices\web.environment.config

但我想在目标块之外初始化此 ItemGroup 。像这样:

<PropertyGroup>
  <Cfgs>@(ApplicationToDeploy->'%(RootDir)%(Directory)*.config')</Cfgs>
</PropertyGroup>

<ItemGroup>
  <InputConfigs Include="$(Cfgs)" />
</ItemGroup>

<Target Name="111">
  <Message Text="Cfgs: @(InputConfigs)"/>
</Target>

当我在Target块之外执行此操作时,我得到了这个:

Cfgs: C:\Sources\WebServices\11\WebServices\11.WebServices\*.config;C:\Sources\WebServices\22\WebServices\22.WebServices\*.config;C:\Sources\WebServices\33\WebServices\33.WebServices\*.config

我不明白发生了什么。是否可以在目标块之外获得相同的结果?

1 个答案:

答案 0 :(得分:4)

  

我不明白发生了什么。

此行为是MSBuild evaluation order

的效果

在构建的评估阶段:

  • 按照它们的顺序定义和修改属性 出现。属性函数被执行。表格中的属性值 $(PropertyName)在表达式中展开。财产价值 设置为展开的表达式。
  • 项目定义按它们出现的顺序定义和修改。属性函数已在表达式中扩展。元数据值设置为扩展表达式。
  • 项目类型按其出现的顺序定义和修改。形式为@(ItemType)的项目值被扩展。项目转换也被扩展。属性函数和值已在表达式中扩展。项目列表和元数据值设置为扩展表达式。

在构建的执行阶段:

  • 在目标中定义的属性和项目 按照它们出现的顺序一起评估。属性 执行函数并在其中扩展属性值 表达式。项目值和项目转换也会扩展。 属性值,项类型值和元数据值设置为 扩展的表达。“

该链接还有另一个关键点“(...)字符串扩展取决于构建阶段。”

您正在使用属性“Cfgs”以递归方式映射项目的文件夹并定义通配符以配置文件(*.config)。当您在目标中定义'Cfgs'时,InputConfigs将接收扩展的Cfgs值(以分号分隔的文件夹列表),并只解析通配符。另一方面,当你定义'Cfgs'OUTSIDE目标时,InputConfigs会收到未扩展的Cfgs值(@(ApplicationToDeploy->'%(RootDir)%(Directory)*.cs')。当InputConfigs扩展它时,它会产生分号分隔的文件夹列表,但它无法解析通配符(*.config)

  

是否可以在Target块之外获得相同的结果?

我认为InputConfigs应该始终接收扩展的目录列表。扩展是在构建的执行阶段进行的。在这个阶段,只有 评估属性和项目在目标中定义的项目。因此,我会将所有初始化保留在“初始化”目标块中。我并不是说在Target块之外做它是不可能的,但由于提到的原因它似乎不合逻辑。 =]

希望这有帮助,