Here is my sample script. I have a console application and a class library DLL (name it libraryA). The LibraryA DLL references Oracle.DataAccess.dll version 4.112.2.0. Oracle DLL is located in the GAC. The reference to the Oracle DLL in LibraryA is "Copy Locally = False". So far, so good. If you create libraries libraryA, then Oracle.DataAccess.dll does not appear in its output directory. OK. Now I refer to the dll library in my console application. The link to the dll library is "copy local = true". Now, when I create a console application, Oracle.DataAcess.dll appears in the output directory for the console application. However, it seems that the only DLL that acts this way is the Oracle dll. Here is the complete code from LibraryA
public void Foo() { Oracle.DataAccess.Client.OracleConnection c = new Oracle.DataAccess.Client.OracleConnection(); WebMatrix.WebData.OAuthAccountData x = new WebMatrix.WebData.OAuthAccountData("asd", "asd"); DevExpress.Web.ASPxCallback.ASPxCallback cvv = new DevExpress.Web.ASPxCallback.ASPxCallback(); }
WebMatrix and DevExpress are also located in the GAC, like the Oracle DLL. However, none of these DLLs are output to the output directory, but only to the Oracle dll. What for? What's going on here?
In this case, you can create another class library, call its libraryB, DO NOT put library B in the GAC, link LibraryB from LibraryA and set copy local = false. Even when you do this, libraryB is not copied to the output directory of the console application. Of course, in this case, the program explodes because it cannot find the B library, but at least Visual Studio respects the local copy = false flag. What is the difference between this stupid Oracle DLL?
Oh, one more funny thing. If in my console application I explicitly add a link to Oracle.DataAccess.dll and say copy local = false, then it does not appear in the output directory. It seems pretty funny that in order for the DLL not to appear in the output directory, I have to really reference it :)
Edit:
One more clue. Oracle, to torture developers, does not have one DLL built for AnyCPU. They have x86 and x64 versions. In my case, I refer to the x86 version and build for AnyCPU. However, if I build for x86 (to match the oracle dll), then the Oracle DLL is not copied to the output directory. when creating in AnyCPU, MSBUILD says: msgstr "MSB3270 warning: between the processor architecture of the project" MSIL "and the processor architecture of the help" Oracle.DataAccess, Version = 4.112.2.0, Culture = neutral, PublicKeyToken = 89b483f429c47342, processorArchitecture = x86 "," x86 ". This mismatch may lead to runtime failures. Please consider changing the target processor architecture of your project through Configuration Manager to align processor architectures between your project and links, or to accept link dependencies with a processor architecture that matches exists a target processor architecture of your project. " So it seems that Msbuild ultimately decided that, well, you have a mismatch, so let me continue and copy this DLL into your output directory, thereby ensuring that your application explodes. :)