The assembly will be copied locally if it should not be

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. :)

+4
source share
2 answers

By not referring to it, you allow the use of implicit rules. Well, the implicit default value here is "copy it locally" because most dlls are not in the GAC. The IDE has a crazy concept of β€œgetting it to work,” which means β€œsuppose it won't be in the GAC”.

If you want to use explicit rules, then yes: you need to say what you want. And how do you do this by adding a link and then setting the options you need.

+4
source

After carefully examining what looks like the same problem in the solution I'm working on, we found that this problem was caused by a new check, which was introduced with the release of .NET 4.5, as mentioned here : during assembly, links are now checked to make sure their processor type matches their project type.

Although we have not seen such an error in the build log before, on the affected machines we see a message stating that the projects are built for MSIL and the DLL is built for x86 - instead of creating one DLL created for all processors, the third-party creator provides two separate libraries for x86 and x64, both of which are in our GAC. Before entering this check, the system will use the DLL from the GAC and select the appropriate version, but it seems that after installing .NET 4.5, the build process determines that none of the versions in the GAC is acceptable, so it draws a local copy.

We could not identify any way to disable this behavior, so our permission settings should either simply add a post-build event to delete local copies, or (as mentioned in the question) add links to the problem DLLs in all projects that reference our "Library A" and then set these links to "copy local = false", which also prevents copying the broken local version to the output file.

0
source

All Articles