.NET Reference "Copy Local" True / False Being Set Based on Contents of GAC

D-Sect picture D-Sect · Mar 20, 2010 · Viewed 18.5k times · Source

We had a very interesting problem with a Win Forms project. It's been resolved. We know what happened, but we want to understand why it happened. This may help other people out in the future who have a similar problem.

The WinForms project failed on 2 of our client's PCs. The error was an obscure kernel.dll error. The project ran fine on 3 other PCs.

We found that a .DLL (log4net.dll - a very popular open-source logging library) was missing from our release folder. It was previously in our release folder. Why was it missing in this latest release?

It was missing because I must have installed a program on my Dev box that used log4net.dll and it was added to the Global Assembly Cache.

When I checked the solution's references for log4net.dll, they were changed to "copy local=FALSE". They must have changed automatically because log4net.dll was present in my GAC.

Here's where my question starts:

Why did my reference for log4net.dll get changed from COPY LOCAL = TRUE to COPY LOCAL = FALSE? I suspect it's because it was added to my GAC by another program.

How can we prevent this from happening again? As it stands now, if I install a piece of software that uses a common library and it adds it to my GAC, then my SLNs that reference that DLL will change from Copy Local TRUE to FALSE.

Answer

Hans Passant picture Hans Passant · Mar 20, 2010

That happened because it doesn't make any sense to have Copy Local = True if an assembly is installed in the GAC. Because that local copy will never be used, the GAC is always searched first. Leaving it unchanged would cause major confusion, you'd think you are using the local copy but get another one instead. Changing it causes a confusion too, if you don't notice it, that could perhaps have been addressed with a message box at solution load time.

Log4net is a troublemaker, there are way too many versions in the wild without any deployment procedure that ensures that those versions don't bite each other. Something Apache apparently just didn't want to address, leaving it up to the programmer instead. Having products that take a dependency on Log4net and do something about the perceived DLL Hell risk is somewhat inevitable. Giving you a DLL Hell problem in return.

No clean simple answers, beyond being aware what's installed on your machine. Consider posting to connect.microsoft.com to ask for a warning when Visual Studio automatically updates the Copy Local property. It is a reasonable ask.