Using the contents of a file to define an MSBuild property

Raymond Chen

Say you want to define a property in your MSBuild project file (vcxproj, csproj, etc.) and have the property value come from a file. You might try using the Read­Lines­From­File task to get the contents:

  <Target Name="DefineMagic">
    <ReadLinesFromFile File=".\magic.txt">
      <Output TaskParameter="Lines" PropertyName="Magic" />
    </ReadLinesFromFile>
  </Target>
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>MAGIC="$(Magic)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>

This doesn’t work because the Target doesn’t run until after the Item­Definition­Group is already defined. MSBuild evaluates Property­Group and Item­Group elements before running any Targets, By the time you execute the Read­Lines­From­File task, it’s too late.

Instead, you can use the Read­All­Text MSBuild property function to read the text into a property.

  <PropertyGroup>
    <Magic>$([System.IO.File]::ReadAllText('.\magic.txt').TrimEnd())</Magic>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>MAGIC="$(Magic)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>

You can see an example of this trick in the WindowsAppSDK build properties.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Vijay Anand E G 0

    I’ve been using this approach for quite a long, especially for the NuGet package release notes.

    The only downside is the file needs to be physically present in the path mentioned. So relative path needs to be carefully managed.

    <PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)\release-notes.txt"))</PackageReleaseNotes>
  • Joshua Hudson 0

    MSBuild is so bad I’d love to cut it out of the build process, but trying to run the dotnet runtime any other way is its own pain.

    Most of the actual build code is C# code inside dotnet.exe with no other entry point.

Feedback usabilla icon