C# – How to make odp.net 12c to work with other oracle client

cdllodp.netoracle

I have oracle 10g client(full) and 11g instant client installed on my machine.
I am trying to use ODP.NET 12c. Here is what I did.

  1. Added Oracle.DataAccess.dll to References.
  2. Copied OraOps12.dll to the folder where my executable is.

When running I got "Unable to load DLL 'OraOps12.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)".

I think it could be due to dependency issue. So I further copied 12c's

  • oci.dll
  • oraociei12.dll
  • orannzsbb12.dll

I then still got other dependency errors. I don't want to copy the whole InstantClient though.

My goal is to get the app to work with other versions of Oracle client.
Our customers have different version of Oracle client installed. So any way to get the app (ODAC12c) work with customers' current version of Oracle client without having to install 12c client?

Thanks,

Update:
I forgot to mention a few things

  1. my ODAC is 32bit and I compiled my app on x86.

  2. I didn't use Oracle.ManagedDataAccess.dll because it does not include BULKCOPY classs. If anyone knows a version of Oracle.ManagedDataAccess.dll that includes bulkcopy class please let me know.

  3. Our customers already has different versions of Oracle client installed for other apps and they don't want to change their environment just for this new app. So my goal becomes to make one version of ODAC in my app work with different versions of existing Oracle client (each customer environment is different). Is this possible and if yes, how?

Best Answer

You know, I just spent 5 minutes looking for the guy that I remember attempting this before...and it turned out to be you shawn ;).

Honestly, to rely on what the client has installed is a crap-shoot. I would use the full xcopy package, get it working, and then work backwards, deleting what is not needed.

  • Don't run the install.bat that comes with it. Doing so adds registry entries that aid in locating the unmanaged binaries, but you also risk messing with a client installed copy.
  • Drop the whole xcopy install into your app's folder as a subfolder.
  • Instead, set the DllPath to this new subfolder

Example:

<oracle.dataaccess.client>
  <settings>
    <add name="DllPath" value="C:\app\user\product\11.1.0\client_1\BIN"/>
  • Then set the Oracle_Home environment variable

Example:

Environment.SetEnvironmentVariable("ORACLE_HOME", @"C:\app\user\product\11.1.0\client_1\");

This article does something similar: http://dbaportal.eu/2013/02/22/true-xcopy-runtime-for-oracle-odp-net-application/

He even adds a policy to redirect in case he has referenced projects that reference a particular version of Oracle.DataAccess.dll

He adds his oracle home with a batch file though. The part I'm not so sure of is that he also adds his new xcopy install to the path with that same batch file. DllPath should take care of that, but if I'm wrong, you can also do that at runtime:

Environment.SetEnvironmentVariable("PATH", @"C:\app\user\product\11.1.0\client_1\BIN");

From here, I'd setup some basic unit tests using all the ODP.net functionality you are using and get some positive tests and then work backwards - start deleting what you don't need, running your tests each time. You might be able to use sysinternals procexp to show loaded dlls (or procmon to show access to the files). Just loading your tests might be enough to lock the files so you can delete all the ones that aren't locked.

I'm not sure doing this is supported. Then again Oracle does list "the current application's directory" in the unmanaged search order so they didn't close the door either.

EDIT: Found one of the links of other people doing this: http://alderprogs.blogspot.com/2009/04/deploying-odpnet-with-oracle-instant.html

I'm not sure why but they download the instant client separately (it's already part of the xcopy package).

EDIT 4/15/2016: If you're reading this these days note two things. 1) I don't think setting the environment variables are necessary if you are already setting DllPath. 2) I don't think this is worth doing when the managed provider now only requires one or two dlls.

Related Topic