Using MSBuild PropertyGroup Outside Target Block

I have a collection of project files:

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

I am trying to get a collection of .config files for these projects:

 <Target Name="111"> <PropertyGroup> <Cfgs>@(ApplicationToDeploy->'%(RootDir)%(Directory)*.config')</Cfgs> </PropertyGroup> <ItemGroup> <InputConfigs Include="$(Cfgs)" /> </ItemGroup> <Message Text="Cfgs: @(InputConfigs)"/> </Target> 

Inside the Target block , everything works fine (I see a collection of Web.Configs, App.Configs, Log4net.Configs, etc.):

 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 

But I want to initialize this ItemGroup outside the Target block. Like this:

 <PropertyGroup> <Cfgs>@(ApplicationToDeploy->'%(RootDir)%(Directory)*.config')</Cfgs> </PropertyGroup> <ItemGroup> <InputConfigs Include="$(Cfgs)" /> </ItemGroup> <Target Name="111"> <Message Text="Cfgs: @(InputConfigs)"/> </Target> 

And when I do this outside the target block, I get the following:

 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 

I do not understand what's going on. Is it possible to get the same result outside the Target block?

+4
source share
1 answer

I do not understand what's going on.

This behavior is a consequence of the MSBuild evaluation order :

At the assembly evaluation stage:

  • Properties are defined and changed in the order in which they appear. Property functions are performed. Property values ​​in the form of $ (PropertyName) are expanded in expressions. The property value is set to an extended expression.
  • Element definitions are defined and changed in the order in which they are displayed. Property functions have already been extended in expressions. Metadata values ​​are set to extended expressions.
  • Element types are defined and changed in the order in which they are displayed. The values ​​of elements in the form @ (ItemType) are expanded. Transformations of elements are also expanding. Functions and function values ​​have already been expanded in expressions. Element values ​​and metadata values ​​are set to advanced expressions.

At the stage of assembly:

  • Properties and elements that are defined within the goals are evaluated together in the order in which they appear. Property functions are performed and property values ​​expand inside the expression. The values ​​of elements and elements are also expanded. Property values, element type values, and metadata values ​​are set to extended expressions. "

Another key point in this link is "(...) The line extension depends on the build phase.".

You use the Cfgs property to recursively display the folders of your projects AND to define a template for configuration files (*.config) . When you define the "Cfgs" INSIDE target, InputConfigs gets the extended Cfgs value (semicolon-separated string list of folders) and just allows wildcards. On the other hand, when you define "Cfgs" OUTSIDE target, InputConfigs gets the unexpanded value of Cfgs ( @(ApplicationToDeploy->'%(RootDir)%(Directory)*.cs') ). When InputConfigs expands it, it appears in the lines of the list separated by semicolons, but it doesn’t allow wildcards (*.config) .

Is it possible to get the same result outside the target block?

I think InputConfigs should always get an extended list of directories. Expansion is carried out at the stage of assembly. At this point, properties and elements defined within the objectives . Thus, I would keep all the initialization inside the "Initialization" block. I do not mean that this cannot be done outside the target block, but for the reasons indicated, this does not seem logical. =]

Hope this helps,

+4
source

All Articles