Estoy recibiendo este error mientras que en mi aplicación .Net
están tratando de hacer una conexión a la base de datos de oracle.
El error dice que Este problema ocurrirá cuando se ejecute en modo de 64 bits con los componentes del cliente de Oracle de 32 bits instalados.
. Pero me he asegurado muchas veces de que el cliente instalado en x64
bit no 32
.
Date Time: 6/8/2014 10:57:55 AM: System.InvalidOperationException: Attempt to load Oracle client libraries threw BadImageFormatException. This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed. ---> System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at System.Data.Common.UnsafeNativeMethods.OCILobCopy2(IntPtr svchp, IntPtr errhp, IntPtr dst_locp, IntPtr src_locp, UInt64 amount, UInt64 dst_offset, UInt64 src_offset)
at System.Data.OracleClient.OCI.DetermineClientVersion()
--- End of inner exception stack trace ---
at System.Data.OracleClient.OCI.DetermineClientVersion()
at System.Data.OracleClient.OracleInternalConnection.OpenOnLocalTransaction(String userName, String password, String serverName, Boolean integratedSecurity, Boolean unicode, Boolean omitOracleConnectionName)
at System.Data.OracleClient.OracleInternalConnection..ctor(OracleConnectionString connectionOptions)
at System.Data.OracleClient.OracleConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.OracleClient.OracleConnection.Open()
at CustomizedSetupInstaller.Runscripts.InitializeDBObjects(String connectionString, String dbProvider)
Una solución es instalar tanto clientes Oracle x86 (32 bits) como x64 en su máquina, entonces no importa en qué arquitectura se ejecute su aplicación.
Aquí una instrucción para instalar el cliente Oracle x86 y x64 en una máquina:
Supuestos: El hogar de Oracle se llama OraClient11g_home1
, la versión del cliente es 11gR2.
Opcionalmente, elimine cualquier cliente Oracle instalado (consulte https://stackoverflow.com/questions/8450726/how-to-uninstall-completely-remove-oracle-11g-client si tiene problemas)
Descargue e instale el cliente Oracle x86, por ejemplo en C:\Oracle\11.2\Client_x86
.
Descargue e instale el Cliente Oracle x64 en otra carpeta, por ejemplo en C:\racle\11.2\Client_x64
.
Abra la herramienta de línea de comandos, vaya a la carpeta %WINDIR%\System32, normalmente C:\Windows\System32
y cree un enlace simbólico ora112
a la carpeta C:\racle\11.2\Client_x64
(consulte la sección de comandos más adelante)
Cambie a la carpeta %WINDIR%\SysWOW64, normalmente C:\Windows\SysWOW64
y cree un enlace simbólico ora112
a la carpeta C:\racle\11.2\Client_x86
, (ver más abajo)
Modifique la variable de entorno PATH
, sustituya todas las entradas como C:\racle\11.2\Client_x86
y C:\racle\11.2\Client_x64
por C:\Windows\System32\ora112
, respectivamente su subcarpeta bin
. Nota: C:\Windows\SysWOW64\ora112
no debe estar en el entorno PATH.
Si es necesario, establezca su variable de entorno ORACLE_HOME
a C:\Windows\System32\ora112
.
Abra el Editor del Registro. Establezca el valor del Registro HKLM\Software\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME
a C:\Windows\System32\ora112
.
Establezca el valor del Registro HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME
a C:\Windows\System32\ora112
(no C:\Windows\SysWOW64\ora112
)
Ya ha terminado. Ahora puede utilizar el cliente Oracle x86 y x64 sin problemas, es decir, una aplicación x86 cargará las librerías x86 y una aplicación x64 cargará las librerías x64 sin necesidad de realizar ninguna otra modificación en su sistema.
Probablemente sea una buena opción establecer su variable de entorno TNS_ADMIN
(resp. las entradas TNS_ADMIN
en el Registro) en una ubicación común, por ejemplo TNS_ADMIN=C:\Oracle\Common\network
.
Comandos para crear enlaces simbólicos:
cd C:\Windows\System32 mklink /d ora112 C:\Oracle\11.2\Client_x64 cd C:\Windows\SysWOW64 mklink /d ora112 C:\Oracle\11.2\Client_x86
Notas:
Ambos enlaces simbólicos deben tener el mismo nombre, por ejemplo ora112
.
A pesar de sus nombres, la carpeta C:\Windows\System32
contiene las bibliotecas x64, mientras que C:\Windows\SysWOW64
contiene las bibliotecas x86 (32 bits). No se confunda.
En mi situación, el cliente de 32 bits de Oracle 11.2 estaba instalado en mi SO Windows** 2008 R2 de 64 bits.
**Mi solución: en la configuración avanzada del grupo de aplicaciones asignado a mi aplicación ASP.NET, establecí la opción "Habilitar aplicaciones de 32 bits" en "Verdadero".
Por favor, vea a continuación el script de prueba independiente .ashx que utilicé para probar la capacidad de conectarse a Oracle. Antes de hacer el cambio de Application Pool, su respuesta fue:
idioma: lang-none -->
[Running as 64-bit] Connection failed.
...y después del cambio de Application Pool:
idioma: lang-none -->
[Running as 32-bit] Connection succeeded.
TestOracle.ashx - Script para probar una conexión a Oracle a través de System.Data.OracleClient:
Para usar: Cambia las variables de usuario, contraseña y host según corresponda.
Tenga en cuenta que este script puede utilizarse de forma independiente sin alterar el archivo de proyecto de su aplicación web ASP.NET. Sólo tienes que soltarlo en la carpeta de tu aplicación.
<%@ WebHandler Language="C#" Class="Handler1" %>
<%@ Assembly Name="System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" %>
using System;
using System.Data.OracleClient;
using System.Web;
public class Handler1 : IHttpHandler
{
private static readonly string m_User = "USER";
private static readonly string m_Password = "PASSWORD";
private static readonly string m_Host = "HOST";
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string result = TestOracleConnection();
context.Response.Write(result);
}
public bool IsReusable
{
get { return false; }
}
private string TestOracleConnection()
{
string result = IntPtr.Size == 8 ?
"[Running as 64-bit]" : "[Running as 32-bit]";
try
{
string connString = String.Format(
"Data Source={0};Password={1};User ID={2};",
m_Host, m_User, m_Password);
OracleConnection oradb = new OracleConnection();
oradb.ConnectionString = connString;
oradb.Open();
oradb.Close();
result += " Connection succeeded.";
}
catch
{
result += " Connection failed.";
}
return result;
}
}
BadImageFormatException se produce cuando una dll de 32 bits (x86) llama a una dll de 64 bits o viceversa. Si utiliza AnyCPU para su ejecutable de entrada, cuando se ejecuta en una máquina de 64 bits se ejecutará como de 64 bits, sin embargo, si luego llama a una dll de 32 bits se obtiene la excepción que es la razón por AnyCPU no es siempre la respuesta.
Yo tiendo a construir todo como 32bit (x86) ya que todavía tenemos que interactuar con algunos componentes antiguos hechos en VB6 (32bit (x86)). Mientras que el rendimiento puede ser mejor para las máquinas de 64 bits si construimos en AnyCPU la fiabilidad es más importante para nosotros.
Yo sugeriría tratar de construir todos los componentes en 32 bits (x86), a menos que usted está haciendo algunas cosas realmente intensivo dudo que va a hacer mucha diferencia.