Search code examples
msbuildsandcastle

Why does a property value work when being used as an attribute value and not an Item value in msbuild?


I am trying to build the documentation for my application using Sandcastle Help File Builder. One requirement is that I must specify the documentation source for e.g.:

<DocumentationSources>
    <DocumentationSource sourceFile="@(DocumentationSourceFiles)" xmlns="" />
</DocumentationSources>

I have defined @(DocumentationSourceFiles) in a separate file as follows:

  <ItemGroup>
     <DocumentationSourceFiles Include="..\src\**\*.exe"></DocumentationSourceFiles>
  </ItemGroup>

I then imported this file in the .shfbproj file and used it as stated above. The problem is that @(DocumentationSourceFiles) is not being recognized as a list of items but merely as a string. Am I doing anything wrong? If I were to change @(DocumentationSourceFiles) into a property with a single value like:

<PropertyGroup>
    <DocumentationSourceFiles>S:\SVN\myApp\src\myAppName\Debug\bin\myApp</DocumentationSourceFiles>
</PropertyGroup>

And then use:

<DocumentationSources>
    <DocumentationSource sourceFile="$(DocumentationSourceFiles)" xmlns="" />
</DocumentationSources>

Everything works fine. Any ideas?


Solution

  • Using the notation @(myType) allows a collection of items of type myType to be expanded into a semicolon (;) delimited list of strings, and passed to a parameter. If the parameter is of type string, then the value of the parameter is the list of elements separated by semicolons. If the parameter is an array of strings (string[]), each element is inserted into the array based on the location of the semicolons. If the task parameter is of type ITaskItem[], the value is the contents of the item collection with any metadata attached. To delimit each item with a character other than a semicolon, use the syntax @(myType, 'separator').

    If you want to have each item separately, use the metadata notation : %(ItemCollectionName.ItemMetaDataName)

    <ItemGroup>
      <DocumentationSourceFiles Include="..\src\**\*.exe"></DocumentationSourceFiles>
    </ItemGroup>
    
    <Target Name="TestItem">
      <Message Text="Using @ Notation"/>
      <Message Text="@(DocumentationSourceFiles)"/>
      <Message Text="Using Metadata Notation"/>
      <Message Text="%(DocumentationSourceFiles.RecursiveDir)%(Filename)%(Extension)"/>
    </Target>
    
    > Output:
    Using @ Notation
    ..\src\doc1.exe;..\src\doc2.exe;..\src\subdir\doc3.exe
    Using Metadata Notation
    ..\src\doc1.exe
    ..\src\doc2.exe
    ..\src\subdir\doc3.exe