ODP.NET for both 32bit and 64bit - c#

I am developing application which uses ODP.NET to connect to Oracle DB. I would like to have one version for both 32bit and 64bit machines. The problem is that I couldn't figure out how to build projetc with anycpu target, seems it requires the target to be the same as ODP driver version. So it means that I need to have to versions of the same application one for 32bit and other for 64bit. But the same was not problem while using MS .NET Oracle client (System.Data.OracleClient). Is there a way to have the same behavior using ODP.NET as on MS .NET client?

Just update few years later: Oracle released managed ODP.NET client, so there's no need to bother with x64/x86 in .NET applications any more. You can find more information on Oracle website: http://www.oracle.com/technetwork/topics/dotnet/index-085163.html

The root cause is the ODP.NET's reliance on native OCI DLLs, which of course cannot be "Any CPU".
Theoretically, ODP.NET could detect the "bit-ness" of the current execution in the .NET code and then dynamically load either 32-bit or 64-bit native DLLs accordingly, but that's not how it is currently implemented.
Oracle corporation is currently in the process of implementing a fully managed provider. But until then, we are stuck with having to do separate builds for each "bit-ness".

The default option for any C# project is it will work on both x64 and x86 operating systems.
So it means that I need to have to versions of the same application
one for 32bit and other for 64bit. But the same was not problem while
using MS .NET Oracle client (System.Data.OracleClient).
This is expected....You need to release a x86 version and a x64 version, please take note, x86 application cannot reference a x64 assembly and vice-versa.
The reason the Microsoft reference was different was because its part of the .NET Framework by default.
I cannot download the file where I am at, I do believe that, ODP.NET has a x86 assembly and a x64 assembly.
The correct way is to release a x86 version and a x64 version of your program.

ODP.NET is specifically built for either 32-bit or 64-bit platform. They could have built a single library for AnyCPU which would allow it to be used in a 32-bit or 64-bit process. However, as Branko Dimitrijevic alluded to, the ODP.NET managed dll uses native libraries behind the scenes. Native libraries are platform-specific; thus requiring Oracle to build separate ODP.NET library for each platform. There is no alternative.

Related

Requirement of 64-bit version DLLs in a .NET project

Introduction
I'm working on a .net project, in which I'm using some 32-bit version DLLs. The list of DLLs are:
System.*
Microsoft.*
AWSSDK.*
Npgsql.dll
Newtonsoft.Json.dll
Some other dlls from other vendors
(The list of DLLs is actually too long to be attached in this post without making it too long.)
Requirement
I require 64-bit version DLLs only and at the moment, I only have 32-bit version DLLs in our hand.
Things that I have tried
I verified the DLLs' version using a tool named SigCheck.
I tried to find/convert the DLL version using the following methods:
I searched on the internet and NuGet Package Manager but, I was not able to find 64-bit DLLs.
I tried recompiling the project to 64 bit by changing below setting under project properties:
- Build -> Platform Target -> x64
After compilation, the project DLL got converted to 64-bit. However, the remaining project DLLs' version didn't change.
Question
I would be grateful if someone could share documentation links/steps to convert 32-bit version DLLs to a 64-bit version?
or
Could someone please send us a link to find recompiled 64-bit version of the given DLLs?
Please note that I'm using .NET framework 4.6
Managed .Net dlls are usually platform agnostic. So for most of the libraries you do not need to worry about it, just use nuget to refer to the libraries and you should be good to go. The JIT compiler will take care of compiling the assemblies to 64/32 bit depending on the platform.
The platform target you specify when compiling a dll only sets a flag in the dll. This flag can be changed with CorFlags, but if it has a 32-bit flag it might be for a reason.
The big problem usually occurs when you need to use native assemblies (i.e. c++ dlls). These need to be platform specific. The best solution is to get 64-bit versions of these DLLs, but you would need to get them from the vendor of the libray and update the references in your projects. The most common workaround if you can not get a 64-bit version is to run the library in a separate 32-bit process.

How do .NET Framework classes reference native Windows DLLs without becoming bitness-specific?

I've read many questions and answers indicating that if I want to link my C# project against native libraries, I can't use AnyCPU platform target but must make separate 32- and 64-bit builds, each linked against the native DLL of the appropriate bitness.
This makes me wonder how the .NET Framework assemblies themselves are, or at least appear to be, built for AnyCPU. That is, when adding a reference to my GUI application, why don't I have to pick the 32-bit or 64-bit version of System.Windows.Forms? I thought this might just be some Visual Studio magic that would resolve to the appropriate GAC subdirectory (GAC_32 or GAC_64), but I searched for System.Windows.Forms.dll in the GAC and found it in:
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll
Note the "GAC_MSIL". So how does this DLL manage to wrap a native 32-bit API yet remain linkable in a 64-bit application? And why can't I use a similar strategy to make a single C# DLL that links against a native 32-bit library yet remains runnable in 64-bit mode?
Option 1: In GAC you may register 2 versions of assembly one 32 and one 64 bit with exactly same names. Oracle DB Driver for .NET uses this strategy.
Option 2: With your assembly that will be AnyCPU deploy two versions of native DLL and choose proper DLL at runtime (SQLite works like that). As it turns out .NET Framework is intelligent enough to load proper version of native DLL via P/Invoke (Using a 32bit or 64bit dll in C# DllImport)
I had the same problem and ended up using Fody Costura
DLL Files will be shipped as embedded ressources and the lib takes care of the bitness.
You could find an example for SQLite here
The problem I have encountered was that your application needs to have access to the Windows Temp folder to create the assemblies from the ressource. If you dont need it, you could disable it using a config setting createtemporaryassemblies

SQLite with VS2012 and .NET 4.5 -- ANY CPU Build

I've tried looking through the answers for related questions, but haven't found anything that isn't a few years old (unsure if they are still the go-to answer) or that answers my question fully.
Requirements:
I'm developing a C# application that is to run on BOTH 32-bit and 64-bit computers. My client does NOT want to create two different releases based on x86 vs x64.
We're using SQLite, VS2012, and .NET 4.5. Here are the available DLLs for SQLite: http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
Unfortunately, the DLLs are split into 32-bit or 64-bit releases.
Questions:
Is it possible to include both DLLs and switch over them based on processor? How do I do this?
I've read a bit about the GAC, and from what I've read, it's a local solution. To implement this for my application I'd have to install the DLLs to the GAC for every installation, correct?
Can I force the program to run in 32-bit mode in a 64-bit environment, thus losing the 64-bit advantages but being able to run my program in both environments without issue?
Some possible answers that I'm unsure would work for my situation:
See most recent answer (third one down): 64-bit SQLite.dll and Any CPU
The answer from 2012 seemed promising, but the first comment on that answer dashed my hopes: Options for using System.Data.SQLite in a 32bit and 64bit C# world
Yes. Just use the NuGet package System.Data.SQLite. It will install an x86 and x64 subdirectory into your project and, when compiled, into your bin. The 32 bit and 64 bit interop DLLs are copied into those and selected appropriately at runtime based on your CPU. So you build with "Any CPU" selected and can run your application on 32 or 64 bit Windows.

Need to upgrade from .Net 2 to a newer version?

We have a small application that is based on the .NET 2 Framework (C#) and is compatible with WindowsXP to Windows 8 but only 32bit (because our build machine was always 32bit too).
We are now looking to make some changes and also create a 64 bit version now.
My question is now, should we also upgrade to a newer version of the .NET Framework to be ready for the future or can we just stay with our existing .NET Framework 2.
It should still be compatible to Windows XP and all newer Windows (32 and 64 bit).
You can always upgrade it to version 4 of framework and it will still be compatible with the previous versions of windows.
Apart from that, you should always build the .Net application with "Any CPU". It will generate the intermediate code and later the JIT compiler will compile it to either 32bit or 64bit architecture depending on what machine it is being executed.
You should bother about CPU architecture only if you are referencing any unmanaged dll in your .Net application.
yes, It will still remain compatible to windows XP and all newer version of windows too. With upgrade to framework 4, you must have windows XP sp 3 as framework will not install otherwise.
As far as I know, framework 4.5 can only be installed on windows 7 or higher so upgrading to framework 4.5 might not be the option for you.
Upgrading to .NET 3.5 or 4.0 shouldn't pose a problem, the drawback being that fewer people will have the framework installed, and the benefit being that you get a better CLR and can use some new language features.
If you aren't going to change the application source, you won't take advantage of any new language features, and you are only going to add a new dependency (the newer framework) for the end user. I can't see any point in going from 2.0 to 4.0 in that case.
If you are going to continue developing the application at all, then I highly recommend moving to 3.5 or 4.0 to get the new features in those frameworks, most importantly LINQ.
Do note that the 4.5 Framework isn't compatible with Windows XP so you can't upgrade to 4.5 if you want to keep backwards compatibility with XP. As long as you need to target XP you are stuck with 4.0 or less.
As for output platforms, I recommend compiling like this:
Assemblies with native dependencies: Explicitly compile x86 and x64.
Entry point assemblies (.exe's basically): Explicitly compile for x86 and x64.
All other assemblies: Compile as AnyCPU.
Using explicit platform for executables is a good principle because it is least surprising for the user, and allows users on 64bit systems to run the 32bit application if they want. See this blog post for a longer answer http://blogs.msdn.com/b/rmbyers/archive/2009/06/09/anycpu-exes-are-usually-more-trouble-then-they-re-worth.aspx

Does changing build options move where an application is located in the Local Machine Software registry key?

I have a solution where the executable's target platform was initially set to x86, many other projects were set to AnyCPU, and included 3 projects in .Net 3.5 (everything else .Net 4.0). I presume this is why the installer wrote to the HKEY_LOCAL_MACHINE\SOFTWARE registry key.
Recently, I fixed some issues and now all projects are .Net 4.0. Additionally, I set the executable target platform to AnyCPU. I found the application was now installed in HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node.
[sidebar - we have p/invokes - DllImport attributes - that did not
specify a CallingConvention. When this was modified both in
managed and unmanaged code to specifiy Cdecl and __cdecl, we were able to
upgrade dependent projects to .Net 4.0 without receiving a PInvokeStackImbalance exception.]
We develop currently with VS2010 on Windows 7 (64-bit) machines.
My question is: Did the installer write to \SOFTWARE\ initially because some of the projects were .Net 3.5?
Also, if this application is intended to be installed on WindowsXP (32-bit is expected to be supported) machines, is the registry key problematic? Better yet, what should I look for in build options that ensures compatibility on WinXp 32-bit systems?
Only a 64-bit installer will avoid Wow6432Node on a 64-bit operating system. In a Setup project, that's set by the TargetPlatform property of the installer, it defaults to "x86". Change it to "x64" if you changed the C# EXE project's Target platform to AnyCPU. This will also ensure that your program is installed to c:\program files and not c:\program files (x86).
You will thus need to maintain two installers. Bit of a headache, you can avoid it by setting the C# EXE project's Target platform to x86 so both the installer and your program access the key in Wow6432Node.
The pinvoke problem is normally the other way around, 64-bit code has only one calling convention and there's no difference between cdecl and stdcall.

Categories

Resources