]> MSBuild overriding Copy Local property on build 🌐:aligrant.com

MSBuild overriding Copy Local property on build

Alastair Grant | Friday 6 March 2020

I have been exploring the idea of overriding the "copy local" property on a Visual Studio reference (project or dll) at bulid-time.

The Copy Local setting will take a copy of the referenced dll and put it in the output directory of the current project.  In theory, this means that the output directory has a copy of all references needed for the project to work.

There are pros and cons to this, but by default any custom references you add (i.e. not .NET framework references) will have Copy Local set to true.  Disabling it can cause problems with concurrency and file locking, especially if you have more than one instance of Visual Studio open.

From a build perspective, you may wish to want different behaviour for this.  My requirement was looking at disabling copy local for the packaging process that was being used.  Though I had no appetite to go through and change each project by hand.

Step in a custom MSBuild target.  You can extend or override the default build configuration for MSBuild with custom targets.  These need to be put into a file somewhere accessible by MSBuild and the location passed in via the command line, such as: /p:CustomAfterMicrosoftCommonTargets="C:\custom.targets"

This command will merge in any custom build configuration after the default have been applied.

As for the content:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="ModifyCopyLocal" AfterTargets="BeforeBuild">
        <ItemGroup>
            <Reference>
                <Private>False</Private>
            </Reference>
            <ProjectReference>
                <Private>False</Private>
            </ProjectReference>
        </ItemGroup>
    </Target>
</Project>

The custom Target creates a new ItemGroup and changes the settings for references you'd normally find in the *.*proj file (csproj, vbproj, whatever).  Reference handles direct dll references, and ProjectReference handles - you guessed it: project references.

This approach comes with a warning: it's blanket.  If you reference nuget packages etc., this will impact those.

If you want to be more nuanced, you can do this with conditions in the target file, but you may as well just change your settings in the project.

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.