.NET 4.5 "Any CPU" with Perefer 32 bit option : not work for dlls which have 32 and 64 bit versions with XCopy

StackOverflow https://stackoverflow.com/questions/17868039

Question

While I was try to use an embedded database which has both 32-and 64-bit versions like SQLite and SQL Server CE in "C# - ANY CPU"

[ Both provide XCOPY deployment for their 32 and 64 bit versions.

Check the following links: -sql server ce private installation- -XCOPY deployment with sqlite- ]

I noticed that when we check "Prefer 32 bit", XCOPY deployment not work,In that case procoess is not 64 bit but try to load ddl from x64 folder and crashes.

If we uncheck "Prefer 32 bit" it works as 64 bit and find also right dlls.

Even if I make my project x86 then it also works and find right ddls under x86.

Why does "prefer 32 bit" compile option have this behaviour? Is it a bug?

Was it helpful?

Solution

I can confirm Hippias Minor's problem - caused me some headache too. SQLite consists of a managed library that chooses which native DLL to load at run-time (either SQLite.Interop.DLL from x64 or x86 directory). This way it does not need to embed the native library (and is thus more portable - same "xcopy deployment" can work on different architectures). This is also the way SQLite is usually installed from NuGet.

The difference between "x86" and "Any CPU w/ prefer 32-bit" (beside being able to run on ARM) is that the first will set the environment variable PROCESSOR_ARCHITECTURE to "x86" while the second will set it to "AMD64"! The issue is described here: PROCESSOR_ARCHITECTURE returns AMD64 in some 32-bit processes

Therefore SQLite (which is using that as a heuristic) will try to load the 64-bit interop DLL and miserarbly fail since it is infact being run as a 32-bit process.

A workaround might be to check Environment.Is64BitProcess and when that is false manually change the environment variable to "x86".

OTHER TIPS

The primary purpose of the 'Prefer 32 bit' is better processor support with the 'CPU Any' setting.

From What AnyCPU Really Means As Of .NET 4.5 and Visual Studio 11

The difference, then, between “Any CPU 32-bit preferred” and “x86” is only this: a .NET application compiled to x86 will fail to run on an ARM Windows system, but an “Any CPU 32-bit preferred” application will run successfully.

On a x64 processor setting this option is essentially the same as using the x86 compile option.

if (!Environment.Is64BitProcess
      && Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
          .Equals("AMD64", StringComparison.InvariantCultureIgnoreCase))
{
// Workaround the "Any CPU" w/ "Prefer 32-bit" option from .NET 4.5+
  Environment.SetEnvironmentVariable("PROCESSOR_ARCHITECTURE", "x86");
}

before any SQLite code seems to make the thing work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top