MsBuild: sort your Content item file names

I have been playing a bit with MsBuild to process a set of Content items sorted by file name. Content items are the items included in the project, and their Build Action set to Content. Below some sample code on how to achive this, just paste the code in a file sorttest.msbuild, and run as msbuild.exe sorttest.msbuild.


<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="SortTest"
    xmlns="" >

<PropertyGroup> <SortCommand>$(WinDir)\System32\sort.exe</SortCommand> <ContentItemsSortInFile>$(TEMP)\sortfileIn.tmp</ContentItemsSortInFile> <ContentItemsSortOutFile>$(TEMP)\sortfileOut.tmp</ContentItemsSortOutFile> </PropertyGroup>

<ItemGroup> <Content Include="SampleNorthwind\0002_content.testdata.sql" /> <Content Include="SampleNorthwind\0001_initial.schema.sql" /> <Content Include="SampleNorthwind\0004_employee-mobilephone.schema.sql" /> <Content Include="SampleNorthwind\0003_constraints.schema.sql" /> </ItemGroup>

<Target Name="SortTest"> <WriteLinesToFile File="$(ContentItemsSortInFile)" Lines="@(Content)" Overwrite="true"/> <Exec Command="$(SortCommand) $(ContentItemsSortInFile) > $(ContentItemsSortOutFile)"/> <ReadLinesFromFile File="$(ContentItemsSortOutFile)"> <Output TaskParameter="Lines" ItemName="SortedContent"/> </ReadLinesFromFile> <!-- CLEAN UP TEMPORARY FILES --> <Delete Files="$(ContentItemsSortInFile)"/> <Delete Files="$(ContentItemsSortOutFile)"/>

&lt;!--</span><span style="color: rgb(0,128,0)"> DO YOUR ACTION WITH SortedContent, FOR NOW, JUST WRITE IT OUT, ',' SEPARATED </span><span style="color: rgb(0,0,255)">--&gt;
&lt;</span><span style="color: rgb(163,21,21)">Message</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Text</span><span style="color: rgb(0,0,255)">=</span>"<span style="color: rgb(0,0,255)">@(SortedContent,',')</span>"<span style="color: rgb(0,0,255)">/&gt;

</Target> </Project>



My collegue Dion Olsthoorn came with the following solution that is smarter:

  • Get the files from filesystem, is sorted by default
  • Determine all files NOT in project
  • Get again files from filesystem, exclude files NOT in project
  • Result is a set of sorted items as included in the project (as Content items)

Nifty nifty!

Replace this target in the code above:

<Target Name="SortTest" Outputs="%(Content.RelativeDir)">

                <CreateItem Include="%(Content.RelativeDir)*" Exclude="@(Content)">

                               <Output TaskParameter="Include" ItemName="ExcludedSortedContent"/>


                <CreateItem Include="%(Content.RelativeDir)*" Exclude="@(ExcludedSortedContent)">

                               <Output TaskParameter="Include" ItemName="SortedContent"/>


                <Message Text="@(SortedContent,',')" />



  • Thanks for the tip. I never knew the sort.exe file existed!

    After reading your post I was able to implement a check of the fileset for the build of a large application. After compile, I pass the output of the MSBuild task to the ResolveAssemblyReference Task. Next I pass the output of that into the GetAssemblyIdentity task to get the full fusion name of each compiled assembly. I then write the contents of the item list to disk, sort it, and generate a checksum from the file (using MSBuild Extension pack FileSystem.File task). If the checksum of the generated file is different than the master list checked into source control, then I know that someone has checked in a new component, or one with a different version and I send an e-mail to myself!

  • Surprisingly! It is like you understand my mind! You seem to know so much about this, just like you wrote the book in it or something. I think that you can do with some pics to drive the content home a bit, but other than that, this is informative blog post. A good read. I’ll definitely revisit again.

  • Msbuild sort your content item file names.. Reposted it :)

  • Msbuild sort your content item file names.. Reposted it :)

  • Msbuild sort your content item file names.. Awful :)

  • Hi,

    I've added an MSBuild task to my blog that does something similar to what you're attempting to achieve.


Comments have been disabled for this content.