An item exclude only works with the corresponding include on the same actual item tag-- in other words, if the exclude occurs in a later item tag of the same type, it will not affect any files previously included.

For example: suppose you have files a.cs, b.cs, c.cs, a.dll, b.dll, c.dll in the same directory as this project file:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <
Files Include="*.cs" />
  <
Files Include="*.dll" Exclude="a.cs" />
  <
Target Name="Default">
    <
Message Text="@(Files)" />
  </
Target>
</
Project>

Then the output looks like this:

    a.cs;b.cs;c.cs;a.dll;b.dll;c.dll

In particular, a.cs is not excluded.

There are several reasons why an "Exclude" only excludes items from the current item tag, instead of any item in the project file.

  • If an "Exclude" could exclude any item that had previously been included anywhere in the project file, it would make the project file much more confusing and hard to read. Imagine a project file including *.cs, and some imported .TARGETS file excluding a.cs. The user would spend hours trying to figure out why a.cs is not getting compiled. When you see Include="*.cs" in a project file, it's very nice to be able to know for sure that all of the .CS files are being included in the project.
  • There's really no compelling scenario for excluding items from a previous item's Include. The main scenario for "Exclude" is that you're using a wildcard in a particular "Include", but because of the simplistic syntax of wildcards, there's no way to be as specific as you would like. So you tweak the "Include" by specifying an "Exclude". It doesn't really make too much sense to do this for items that have already been included previously.
  • Since you can have multiple items with the same "Include" (with perhaps different item attributes), it's not clear which item we would exclude if the "Exclude" could occur in any random place in the project.
  • With VS integration, it would be extremely difficult to support certain edits to the project file if an item could be excluded anywhere in the project file. Imagine this:

    <ItemGroup>
      <
    Compile Include="b.cs" />
    </
    ItemGroup>
    ....
    <ItemGroup>
      <
    Compile Exclude="a.cs" />
    </
    ItemGroup>

Now the user loads this into the IDE, and in his Solution Explorer, he sees only "b.cs". Now in Solution Explorer, he renames b.cs to a.cs. What should the project file look like now? This type of thing causes unnecessary ambiguity and difficulty.

[ Author: Jeffery Callahan ]