AnyCPu vs ODP.NET - c#

My config: Vs2015 / X64 PC / ODP.NET X86
I've wrote a few DLL on 'Any Cpu' mode and I would like to write programs that use this DLLs and that can be work on X64 and X86 machins.
But I referenced "Oracle.DataAccess.dll" in my Dlls then I've a warning 'ProcessorArchitecture=X86' on Oracle DLL.
How can I do (I can install ODP.NET X64 if necessary) ?
thks

When you compile your DLL with "x86" then also the Oracle.DataAccess.dll must be the x86 version (i.e. 32 bit version)
When you compile your DLL with "x64" then also the Oracle.DataAccess.dll must be the x64 version (i.e. 64 bit version)
For "AnyCPU" it depends, there is no "AnyCPU" version of Oracle.DataAccess.dll. If your application runs on 64-bit Windows it will run as x64 process - thus also Oracle.DataAccess.dll must be the x64 version. If your application runs on 32-bit Windows it will run as x86 process - thus also Oracle.DataAccess.dll must be the x86 version.
To cut a long story short: architecture of Oracle.DataAccess.dll must be the same as the application, i.e. your DLL.
Follow this instruction to run both in parallel:
BadImageFormatException. This will occur when running in 64 bit mode with the 32 bit Oracle client components installed
Update
In your *.csproj, resp. *.vbproj edit your reference to ODP.NET like this:
<Reference Include="Oracle.DataAccess">
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
Attributes like Version=... or processorArchitecture=... are not required. Your application will load the correct Oracle.DataAccess.dll depending on selected architecture and target .NET framework (provided that it is installed properly)

The easiest solution would be to target x86 - a 64-bit operating system can still load and run 32-bit applications, and so this would mean your app can run on both x86 and x64 machines.
The downside is that your app must run as a 32-bit processes, i.e. your process will have a 4GB maximum address space and cannot load 64-bit assemblies. If you try to load your dll in a 64-bit process (e.g. because IIS hasn't been configured to use a 32-bit app pool) you will get a BadImageFormatException.
If thats not acceptable to you then you could try detecting the process version and dynamically loading the correct assembly as per this Stack Overflow answer

All the above mentioned solutions are correct, but I just feel the need to mention Oracle.ManagedDataAcces as it does not care what the bitness is.

Related

Running a 64bit program referencing a 32bit dll using visual studio - C#

I am currently facing a problem where I am referencing a 32bit dll. I tried changing the platform to 86bit which works fine but the requirements are to use a 64bit or 'Any CPU'. When I use the 'Any CPU' platform it somehow does not pick up the dll
Is there a way of using a 32bit dll in 64bit program?
I also read about a workaround of 'wrapping' which was not clear... can someone elaborate
Is there a way of using a 32bit dll in 64bit program?
In the same process: No.*
However, you could host the dll in a separate child process via something like the Add In Framework (which supports out of process workers).
* Note, I am assuming this dll is either natively compiled, or .NET but compiled explicitly for 32bit only.

Referencing .net 1.1 assemblies from 64 bit applications

I have to upgrade a project from 32 bit to 64 bit. My project is currently on .net 2.0 (will be soon 4.0, but doesn't really matter for this issue). My project is referencing some old .net 1.1 assemblies, that I only have in binary form. As you all know, 64 bit support was added in .net 2.0 only, and I expected my application won't run because of those old assemblies.
However, my application runs on a x64 server in 64 bit mode (no star is shown in Task Manager) while referencing the .net 1.1 dll.
My questions are:
Why does it run? I previously read that you cannot use .net 1.1
assemblies in 64 bit apps.
Are there any shortcomings if I keep the 1.1 assemblies? Or should I invest effort in getting newer versions of those 1.1 assemblies?
EDIT: I forgot to mention that a requirement is to run the application (asp.net) natively in 64 bit. The application runs in 64 bit because I disabled 32 bit compatibility on my application pool.
EDIT2: I just tried to compile and run the application compiled for x64. It works. So it runs in pure 64 bit mode, no questions about it.
A .NET 1.1 assembly contains the same kind of IL as a .NET 2 or .NET 4 assembly. Only the format of the metadata has changed. The jitter doesn't mind translating it to 64-bit machine code and the CLR can read the old metadata format. Only if the .NET 1.1 assembly contains native code will you have a problem. Corflags.exe utility, ILONLY bit. There's no compelling reason to rebuild that assembly.
Is your application running under wow32 (32-bit emulation mode)? Most applications do not really run in x64 mode, they force the application to run in wow32 (x86 mode) to keep their backward compatibility on older x86 systems. Otherwise the application would run only on x64 systems but not on x86.
Forcing the application to run in x86 mode (even on x64 systems) allows to run ony any manchine no matter if its a 32 or 64 bit windows OS.

BadImageFormatException on DLL load and Provider not registered on local machine issue

I am running a .NET 4.0 application, Access database on a Windows 7 x64 bit OS + Office 2010 (64-bit compatible provider Microsoft.ACE.OLEDB.12.0).
Platform target x86:
Provider problem:
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine
Platform target x64 or Any CPU:
DLL file problem:
System.BadImageFormatException: Could not load file or assembly 'Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
You can solve the first problem by installing the 32-bit version of the provider. Download is here.
The second problem is very strange, an interop library should contain IL only and not have a dependency on the processor architecture. When I create an interop DLL from c:\windows\system32\shdocvw.dll and run CorFlags.exe on it then I get this:
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 1
ILONLY : 1
32BIT : 0
Signed : 0
Note how ILONLY is on, 32BIT is off. This should run on a 64-bit machine just fine. I'm not close to one right now to check, try this yourself to compare. To get a better answer you should document which version of Internet Explorer you have installed and whether you used the 64-bit or the 32-bit version of the DLL to generate the interop. The latter is in the c:\windows\syswow64 directory.
As I've noted in the comments, this is likely due to the fact your reference DLL is 32-bit. I recently had this issue, you cannot load DLLs of varying bit-ness into a single process. To get around this, you ideally need to equalise the bit-ness of the DLLs.
If that really isn't an option, you can create a new process to house the offending DLL and marshal the calls across using IPC, this however, is less than ideal. I believe there is also a way to shim a DLL with another DLL of correct bit-ness, but likely under the hood it is marshalling cross-process calls again.
I have used IPC successfully in the past to gain access to a 32-bit DLL from a 64-bit application. Luckily for me, there wasn't anything complicated to marshal, it was basic chunky request-response semantics.
You can change the build Platform target on your project for x86 as a temporary solution.

Unable to load assembly on XP 64bit

I have compiled a .NET application using Any CPU option. This .NET application uses an unmanaged dll (managed wrapper) that encapsulated C++ calls. This .NET wrapper resides in GAC.
When I run the .NET application it runs fine on XP 32 bit. But when I run it on XP 64 bit, it fails and gives the following exception:
Could not load file or assembly "Dll name, version, Culture=neutral, PublicKeyToken" or one of its dependencies.
How do I resolve this?
You need to use the x86 CPU option. If you know that one of your unmanaged dependencies is 32bit then you need to build your solution with the x86 option for the CPU. This ensures that even on a 64bit operating system your application will be run in a 32 bit process.
This is required because its not possible to load 32 bit compiled code into a 64 bit process.
You need to make sure your unmanaged dll is also 64bit capable and within the search path.
You can find some explanation on Microsoft Connect website

Do I need to install both the 64-bit *and* x86 version of .Net SP2?

So I downloaded the .net 2.0 sp2 redistributable "NetFx20SP2_x64.exe" from the following site:
http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=5B2C0358-915B-4EB5-9B1D-10E506DA9D0F&displaylang=en
Deployed on my x64 win2k3 server from which I run IIS in x86 mode. On the same server I also run services and utilities in x64 bit mode.
So the question is easy, do I also need to install the "NetFx20SP2_x86.exe" version from the aforementioned link, or does the x64-bit include it already?
If you try to install NetFx20SP2_x86.exe on a x64 system you will get the following error message:
Cannot install on a 32-bit operating
system
If you have already installed the .NET x64 runtime, you actually get both x64 and x86 versions. The one that will be used depends on which platform the assembly is compiled against (the /platform compiler switch). For AnyCPU, it will use x64 otherwise, it will use whatever was specified.

Categories