MSBuild ProjectReference:private ("Copy Local") - what are the allowed values and behaviour?

Martin Ba picture Martin Ba · Oct 2, 2014 · Viewed 28.2k times · Source

TL;DR Is there any official documentation that describes in detail how the <private> / "Copy Local" option works with MSBuild? And what values are supposed to go into it?


When you add a project reference from one project in Visual Studio to another, it will add a <ProjectReference Include=".....csproj"> to the .csproj MSBuild file.

When you add a file reference from one project in Visual Studio to an assembly file in the file system, it will add a <Reference Include="Foo"> <HintPath>....Foo.dll</HintPath> ... to the .csproj MSBuild file.

In both cases, for the Visual Studio Setting Copy Local = True|False, a sub-element <Private>True</Private> or <Private>False</Private> will be added.

Referenceand ProjectReference seem to be documented under Common MSBuild Project Items:

<ProjectReference>
  Represents a reference to another project.

  Item Name    Description
  -------------------------
   Name         ...
   Project      ...
   Package      ...

<Reference>
  Represents an assembly (managed) reference in the project.

  Item Name     Description
  --------------------------
   HintPath      Optional string. Relative or absolute path of the assembly.
   Name          ...
   ...
   Private       Optional string. Determines whether to copy the file to the output directory. 
                 Values are:
                     1. Never
                     2. Always
                     3. PreserveNewest

You will notice that,

  1. ProjectReference doesn't document the <private> Item at all
  2. Reference does not list Trueor False as possible values.

So. Huh? Is there any official documentation (I'll be more than happy with a good blog entry) that describes in detail how the <private> option works? Are the doc's just dead wrong or is there something more to it?


Example snippet from my VS 2013 Express here:

...
  <ItemGroup>
    <Reference Include="ClassLibrary2">
      <HintPath>C:\Somewhere\ClassLibrary2.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System" />
...
  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj">
      <Project>{861dd746-de2e-4961-94db-4bb5b05effe9}</Project>
      <Name>ClassLibrary1</Name>
      <Private>False</Private>
    </ProjectReference>
...

Answer

Matt Slagle picture Matt Slagle · Apr 17, 2015

For Reference and ProjectReference items, the accepted values for Private are: True or False

This property in msbuild corresponds with the project reference property in VS as Copy Local.

I got the above answer by manually setting the reference properties in VS and viewing the xml. I couldn't find official documentation of the Private item metadata.

Checking the docs at https://msdn.microsoft.com/en-us/library/bb629388.aspx shows the accepted values as Never, Always, and PreserveNewest. These seem to be wrong and only available for the CopyLocal metadata, which is used on Content, None, and other file items.