There are cases where you don’t want referenced assemblies to be copied to your output folder.

E.g. you write a plugin for an existing application, which provides a library declaring its contracts. Since the application will load that contract assembly itself, there’s no need for a second copy of the assembly in your plugin folder.

“But you can configure Visual Studio not to copy a reference to the output folder,” you may say. Well, that’s right. In the properties of a referenced assembly you can simply set Copy Local to False.

But…

If you’re an avid user of NuGet like I am, every time you update a package, the old references are removed from your project and the new ones will be added, and Copy Local will be True again. Do you think you will always remember to change that property back to False whenever you update a package? I don’t know about you, but I won’t.

Therefore, here’s a little trick I use in such cases. I have a little MSBuild file which suppresses any referenced assembly to be copied to the output folder:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!-- make all references non-private, so they won't be copied to the output folder -->
  <Target Name="ClearReferenceCopyLocalPaths" AfterTargets="ResolveAssemblyReferences">
    <ItemGroup>
      <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" />
    </ItemGroup>
  </Target>

</Project>

Save that snippet to a file i.e. PreBuild.targets, and include it in your project file like this:

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
  <Import Project="PreBuild.targets" />

That’s it. From now on the output folder will only contain your assembly (along with other build artifacts such as the pdb file, of course)

Tags:

Updated:

Comments

Matt Davis

Is there a way to do it such that the referenced assemblies get copied to the parent directory of the output directory instead? For example, I want my plugins to copy to the the Debug\plugins folder (i.e., the output directory), but I want all referenced assemblies for each plugin to be copied to the parent directory of the output directory.

Thomas Freudenberg

@Matt, the item group ReferenceCopyLocalPaths contains all referenced assembies. So before removing them from the item group, you should be able to copy them to a different folder with the Copy Task.

I also found this Stack Overflow question, one of the answers may help you too: https://stackoverflow.com/questions/55946010/how-to-specify-output-folder-for-the-referenced-nuget-packages

Matt Davis

Just circling back on this. The Copy task worked. Thanks so much.

In case others land here…

Take care to use DestinationFolder, not DestinationFiles.

Colby Africa

Beauty. Thank you, bud. I want preparing to do something archaic with post-build events and batch files.

Leave a Comment

Your email address will not be published. Required fields are marked *

Loading...