45

I am wondering what copy-local=true for references exactly does. Does it copy the referenced assembly along with all of its dependencies to the output directory?

My scenario is the following: I have a custom log wrapper that utilizes log4net. I build a release assembly of MyLogWrapper.dll with log4net.dll reference set to copy-local true. Referencing MyLogWrapper.dll from MyProject with copy local set to true should result in log4net.dll being copied as well right? I am only referencing MyLogWrapper.dll and none of its dependencies in MyProject. log4net.dll is not being copied to MyProject output directory but all other dependencies of MyLogWrapper are. What could be the problem?

I have made some more experiments and it seems that if I remove the assembly (log4net.dll) from GAC it starts to get copied locally. Can anyone confirm that this is the problem?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Fadeproof
  • 3,038
  • 5
  • 31
  • 42

6 Answers6

31

Unfortunately it appears that according to the following statement taken from the MSDN documentation the CopyLocal functionality does not work as expected for assemblies already in the GAC.

If you deploy an application that contains a reference to a custom component that is registered in the GAC, the component will not be deployed with the application, regardless of the CopyLocal setting. In previous versions of Visual Studio, you could set the CopyLocal property on a reference to ensure that the assembly was deployed. Now, you must manually add the assembly to the \Bin folder. This puts all custom code under scrutiny, reducing the risk of publishing custom code with which you are not familiar.

More information can be found at the following page which explains details about how project references work.

MSDN: Project References

slugster
  • 49,403
  • 14
  • 95
  • 145
jpierson
  • 16,435
  • 14
  • 105
  • 149
  • I've added a link below to a post I made on the DataDynamics ActiveReports for .NET 3.0 forum regarding this same issue with regards to dlls deployed with active reports. Strangely I've found that this supposed "by design" behavior seems to depend on the library being reference, for example WPFToolkit.dll seems to copy to the bin folder regardless if it is through a secondary reference. http://www.datadynamics.com/forums/124306/ShowPost.aspx – jpierson Jul 16 '09 at 10:04
10

After asking this question on MSDN here - it seems that this behaviour is by design. "If you deploy/copy an application that contains a reference to a custom component that is registered in the GAC, the component will not be deployed/copied with the application, regardless of the Copy Local setting."

Fadeproof
  • 3,038
  • 5
  • 31
  • 42
  • VS 2015 makes an exception to that for indirect references via a project reference. For instance VS 2010 doesn't behave like that. https://connect.microsoft.com/VisualStudio/Feedback/Details/1804765 – vezenkov Sep 18 '15 at 08:37
7

There is a trick: set the reference Copy Local to false and then again to true, and Visual Studio adds the Private metadata automatically for that reference. At least VS 2010 does. I recently did this to solve an issue with our TFS Build server which for some weird reason had many Enterprise Library components installed in the GAC, so we had major issues when deploying our project from TFS Drop folder. That false/true trick saved us.

JustAMartin
  • 13,165
  • 18
  • 99
  • 183
  • This did work on my machine but not on our build server. Seems I cannot remove my upvote. – arkod Nov 23 '15 at 12:31
  • If it does not work on newer editions of VS, then, I guess, we have no other choice but modify project files manually to add "copy local" to the references in the project XML file and then later be super careful to avoid touching reference settings in Visual Studio itself. But I'll have to investigate it more, maybe even this manual fix won't be enough if Microsoft has changed the core behavior of msbuild since VS 2010... – JustAMartin Nov 23 '15 at 13:02
5

You need to be a bit wary of copy local as it has caught me out in the past!

Just occasionally, for a particular .dll it will silently fail to copy it to the build folder. Usually this doesn't show up on a dev machine as the dll's are often in the GAC as well (if you have installed a dev tool / library you are using for development) and so you don't notice until it gets distrobuted / bundled into an installer and the required files are missing on a client machine.

There is not much info on this bug, but this thread demonstrates it for a particular library: here.

Having been caught by this, I think it's a good idea (generally in any case) to know exactly which assemblies are required by your project and to have a script or similar automated action which ensures all required componants are present, either when you build, or more likely when you make an installer, or collect files for distribution,

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
xan
  • 7,440
  • 8
  • 43
  • 65
  • Do you recommend using vs post-build events for doing this? – Fadeproof Nov 26 '08 at 12:39
  • I have not used them, so I can't say yes or no. In the case I had, I had a NSIS script which generated the installer for the tool I was writing (a visual app). Rather than just including *.dll in the installer, I updated it to include every assembly by name, so that I was warned if any were missing. – xan Nov 26 '08 at 13:00
  • ... cont. It also sourced the correct assembly from elsewhere if it was missing so that the installer generation didn't fail, but it warned that VS hadn't copied the .dll I needed. – xan Nov 26 '08 at 13:02
4

When local copy is set to true it will copy all the assemmbly whose attribute local copy = tue to the bin direcory of the application.

In your case the dll might be using the other dll so it require that also.

Raj Kumar
  • 6,970
  • 5
  • 30
  • 40
0

I've found that this is no more respected in Visual Studio 2015 with project references if the referenced project has a dependency to a GAC assembly. The GAC assembly is always copied to the root project output and copy local = false being respected only regarding the output of the project holding the reference to the GAC dll.

Connect feedback

vezenkov
  • 4,009
  • 1
  • 26
  • 27