6

我有一个项目文件集合:

<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>

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

但我想在Target块之外初始化这个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

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

4

1 回答 1

6

我不明白发生了什么。

此行为是MSBuild 评估顺序的影响:

在构建的评估阶段:

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

在构建的执行阶段:

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

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

您正在使用属性“Cfgs”递归地映射您的项目文件夹并定义通配符到配置文件(*.config)。当您在目标内部定义“Cfgs”时,InputConfigs 会接收 Cfgs 的扩展值(以分号分隔的文件夹字符串列表),并仅解析通配符。另一方面,当您在目标外部定义 'Cfgs' 时,InputConfigs 会收到 Cfgs ( 的未扩展值@(ApplicationToDeploy->'%(RootDir)%(Directory)*.cs')。当 InputConfigs 扩展它时,它会生成以分号分隔的文件夹字符串列表,但它不会解析通配符(*.config)

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

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

希望这可以帮助,

于 2013-01-15T13:48:50.580 回答