Reputation: 13
I can create MSBuild property, which contain unexpanded property reference. Here is example of it:
Text file property.txt contains single line
$(SomeProperty)
It can be processed with msbuild script like this:
<ItemGroup>
<PropertyFile Include="property.txt"/>
</ItemGroup>
<!-- Standart task for file reading -->
<ReadLinesFromFile File="@(PropertyFile)" >
<Output
TaskParameter="Lines"
ItemName="ItemsFromFile"/>
</ReadLinesFromFile>
<!-- Property LastLine now has value $(SomeProperty) -->
<PropertyGroup>
<LastLine>%(ItemsFromFile.Identity)</LastLine>
</PropertyGroup>
<Message Text="$(LastLine)"/>
Now I want to expand property reference, which contains in CurrentLine. Is it possible?
Upvotes: 1
Views: 1836
Reputation: 9938
If you know in advance all of the properties that are candidates for being the single property listed in the file there is a way to do this with item filtering. Caveats:
1) Specify only the PropertyName in the file, not $(PropertyName), unless you want to parse the string using a property function.
2) There can only be a single line in the file with the approach below, for multiple lines you'll need an extra level of batching.
<ItemGroup>
<PropertyFile Include="property.txt" />
</ItemGroup>
<PropertyGroup>
<SomeProperty>1</SomeProperty>
<SomeOtherProperty>2</SomeOtherProperty>
</PropertyGroup>
<ItemGroup>
<ChooseProperty Include="SomeProperty">
<Value>$(SomeProperty)</Value>
</ChooseProperty>
<ChooseProperty Include="SomeOtherProperty">
<Value>$(SomeOtherProperty)</Value>
</ChooseProperty>
</ItemGroup>
The constructs above establish two candidate properties, $(SomeProperty) and $(SomeOtherProperty). For this example the contents of property.txt was a single line...
SomeProperty
...which correlates to $(SomeProperty) which has a value of 1
<Target Name="ReadItems">
<ReadLinesFromFile File="@(PropertyFile)">
<Output
TaskParameter="Lines"
ItemName="ItemsFromFile"
/>
</ReadLinesFromFile>
</Target>
<Target Name="FilterItems"
Outputs="%(ChooseProperty.Identity)">
<PropertyGroup>
<_ThisProperty>%(ChooseProperty.Identity)</_ThisProperty>
<_ThisValue>%(ChooseProperty.Value)</_ThisValue>
<_ItemFromFile>%(ItemsFromFile.Identity)</_ItemFromFile>
</PropertyGroup>
<ItemGroup Condition="'$(_ItemFromFile)' == '$(_ThisProperty)'">
<_FilteredItems Include="$(_ThisProperty)">
<Value>$(_ThisValue)</Value>
</_FilteredItems>
</ItemGroup>
</Target>
Above are the two dependent targets for the main target below. They use a dependent target to read the file so that it is published into an item group to be used with target batching on the @(ChooseProperty) item group. The key thing to note is the condition on the creation of the @(_FilteredItems) item group, which will contain a single member, due to this...
Condition="'$(_ItemFromFile)' == '$(_ThisProperty)'
...notice that the batched item meta data is transferred to these temporary properties in order to make the condition work (and this is why the file can only contain a single line, so that there is only a single item).
<Target Name="ChoosePropertyFromItem"
DependsOnTargets="ReadItems;FilterItems">
<!-- Standard task for file reading -->
<PropertyGroup>
<LastLine>%(_FilteredItems.Value)</LastLine>
</PropertyGroup>
<Message Text="LastLine='$(LastLine)'" />
</Target>
...finally the $(LastLine) Property is pulled from the single item in @(_FilteredItems). The resulting output is below:
ChoosePropertyFromItem:
LastLine='1'
Changing the property.txt to contain 'SomeOtherProperty' results in this:
ChoosePropertyFromItem:
LastLine='2'
Upvotes: 1
Reputation: 4286
You can't create new properties in such a way. You can't create property names dynamically. You can modify build process. Example
msbuild.exe yourproject.sln /p:UseSomeProp=true
Upvotes: 0