27

I have a library project that has multiple targets, e.g. in the CSPROJ file it has:

<TargetFrameworks>net40;net46;net461;net462;net47</TargetFrameworks>

If I want XML documentation for all combinations of these target frameworks and Debug and Release configurations I have to select each one in turn in the UI using the Build Configuration Manager and then set it to build XML documentation for that combination and each combination is then listed separately as a PropertyGroup in the CSPROJ with the intended output file for the XML documentation.

Is there a better way?

Posting question and answer because I didn't find this documented anywhere else online

Ian Mercer
  • 35,804
  • 6
  • 87
  • 121

2 Answers2

62

An easy way is to set the GenerateDocumentationFile property to true. The VS UI want to set the path, the MSBuild targets will set this property to true if the path is set or set a default path if the GenerateDocumentationFile property is true. So you can add this to your csproj file:

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

If you want to set this to true for all your projects to share it, create a file named Directory.Build.props in your solution's directory with the following content and it will be auto-imported into any projects in the directory hierarchy below:

<Project>
  <PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>
</Project>
Martin Ullrich
  • 78,211
  • 20
  • 211
  • 189
  • Unfortunately this doesn't work with old .NET framework projects – ceztko Oct 16 '18 at 16:32
  • The question was specifically about the new csproj format that is able to multi-target. You could copy the [sdk's code for this](https://github.com/dotnet/sdk/blob/016666d3917b86fc86f0705cf11177bdd8458a1e/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.BeforeCommon.targets#L163-L176) into a [`Directory.Build.targets`](https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2017#directorybuildprops-and-directorybuildtargets) file as well – Martin Ullrich Oct 17 '18 at 05:22
  • Thanks. I tried something similar but using `$(TargetName)` variable, but it didn't work until I put the directive `DocumentationFile` after `Microsoft.CSharp.targets` import. I will the sdk's code you suggest, which use `$(AssemblyName)` instead – ceztko Oct 17 '18 at 09:30
  • Yes, `$(AssemblyName)` is fine anywhere after first imports. I use something like the following and it works: `$(OutputPath)\$(AssemblyName).xml` and it works. – ceztko Nov 04 '18 at 11:27
  • I also tried to put `GenerateDocumentationFile` lines in a `Directory.Build.targets` as you suggest and it worked like a charm! I recommend adding the suggestion in your answer as well to enrich it even better for non SDK projects. – ceztko Jun 05 '19 at 10:34
6

One way to fix this is to include the following in each CSPROJ file:

<!-- Build XML documentation for all combinations of target framework x configuration -->
<PropertyGroup>
 <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 
 </DocumentationFile>
</PropertyGroup>

An even better way is to link to a shared configuration file:

<!-- This must come after any other configuration so that it overwrites it -->
<Import Project="$(MSBuildThisFileDirectory)..\Shared.msbuild" />

... and then place the above lines in that shared configuration file where you can also set all the other solution-wide CSPROJ settings like Product, Company, Copyright, ...

Ian Mercer
  • 35,804
  • 6
  • 87
  • 121