Net` uygulamam oracle veritabanına bağlantı kurmaya çalışırken bu hatayı alıyorum.
Hata, Bu sorun, 32 bit Oracle istemci bileşenleri yüklüyken 64 bit modunda çalıştırıldığında ortaya çıkacaktır
diyor. Ancak istemcinin 32
değil x64
bit olarak yüklendiğinden birçok kez emin oldum.
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)
Bir çözüm, makinenize hem x86 (32 bit) hem de x64 Oracle İstemcilerini yüklemektir, bu durumda uygulamanızın hangi mimaride çalıştığı önemli değildir.
Burada x86 ve x64 Oracle istemcisini tek bir makineye yüklemek için bir talimat bulunmaktadır:
Varsayımlar: Oracle Home OraClient11g_home1
olarak adlandırılır, İstemci Sürümü 11gR2'dir
İsteğe bağlı olarak kurulu Oracle istemcisini kaldırın (sorunla karşılaşırsanız https://stackoverflow.com/questions/8450726/how-to-uninstall-completely-remove-oracle-11g-client adresine bakın)
Oracle x86 İstemcisini indirin ve yükleyin, örneğin C:\Oracle\11.2\Client_x86
içine
Oracle x64 İstemcisini farklı bir klasöre indirin ve yükleyin, örneğin C:\Oracle\11.2\Client_x64
Komut satırı aracını açın, %WINDIR%\System32 klasörüne gidin, tipik olarak C:\Windows\System32
ve C:\Oracle\11.2\Client_x64
klasörüne ora112
sembolik bağlantısını oluşturun (aşağıdaki komutlar bölümüne bakın)
WINDIR%\SysWOW64 klasörüne geçin, tipik olarak C:\Windows\SysWOW64
ve C:\Oracle\11.2\Client_x86
klasörüne ora112
sembolik bağlantısını oluşturun (aşağıya bakın)
PATHortam değişkenini değiştirin,
C:\Oracle\11.2\Client_x86ve
C:\Oracle\11.2\Client_x64gibi tüm girdileri
C:\Windows\System32\ora112, ilgili
\binalt klasörü ile değiştirin. Not:
C:\Windows\SysWOW64\ora112` PATH ortamında olmamalıdır.
Gerekirse ORACLE_HOME
ortam değişkeninizi C:\Windows\System32\ora112
olarak ayarlayın
Kayıt Defteri Düzenleyicinizi açın. Kayıt Defteri değerini HKLM\Software\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME
olarak ayarlayın C:\Windows\System32\ora112
Kayıt Defteri değerini HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME
olarak C:\Windows\System32\ora112
olarak ayarlayın (C:\Windows\SysWOW64\ora112
değil)
İşin bitti! Artık x86 ve x64 Oracle istemcilerini sorunsuz bir şekilde birlikte kullanabilirsiniz, yani bir x86 uygulaması x86 kütüphanelerini yükler, bir x64 uygulaması ise sisteminizde başka bir değişiklik yapmadan x64 kütüphanelerini yükler.
Muhtemelen TNS_ADMIN
ortam değişkeninizi (Kayıt Defterindeki TNS_ADMIN
girdilerine karşılık) ortak bir konuma ayarlamak akıllıca bir seçenektir, örneğin TNS_ADMIN=C:\Oracle\Common\network
.
Sembolik bağlantılar oluşturmak için komutlar:
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
Notlar:
Her iki sembolik bağlantı da aynı isme sahip olmalıdır, örneğin ora112
.
İsimlerine rağmen C:\Windows\System32
klasörü x64 kütüphanelerini içerirken, C:\Windows\SysWOW64
klasörü x86 (32 bit) kütüphanelerini içerir. Kafanız karışmasın.
Benim durumumda, Oracle 11.2 32-bit istemci *64-bit Windows* 2008 R2 işletim sistemimde yüklüydü*.
Benim çözümüm: ASP.NET uygulamama atanan Uygulama Havuzu için Gelişmiş Ayarlar'da 32-Bit Uygulamaları Etkinleştir seçeneğini Doğru olarak ayarladım.
Oracle'a bağlanma yeteneğini test etmek için kullandığım bağımsız .ashx test betiği için lütfen aşağıya bakın. Uygulama Havuzu değişikliğini yapmadan önce yanıtı şöyleydi:
[Running as 64-bit] Connection failed.
...ve Uygulama Havuzu değişikliğinden sonra:
[Running as 32-bit] Connection succeeded.
TestOracle.ashx - System.Data.OracleClient aracılığıyla Oracle Bağlantısını Test Etmek için Komut Dosyası:
Kullanmak için: Kullanıcı, parola ve ana bilgisayar değişkenlerini uygun şekilde değiştirin.
Bu kodun ASP.NET web uygulaması proje dosyanızı bozmadan bağımsız bir şekilde kullanılabileceğini unutmayın. Sadece uygulama klasörünüze bırakı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, bir 32bit (x86) dll bir 64bit dll'yi çağırdığında veya tam tersi olduğunda ortaya çıkar. Giriş çalıştırılabilir dosyanız için AnyCPU kullanıyorsanız, 64bit bir makinede çalıştırıldığında 64bit olarak çalışacaktır, ancak bu daha sonra 32bit bir dll çağırırsa, AnyCPU'nun her zaman cevap olmamasının nedeni olan istisnayı alırsınız.
Hala VB6'da (32bit (x86)) yapılmış bazı eski bileşenlerle arayüz oluşturmak zorunda olduğumuz için her şeyi 32bit (x86) olarak oluşturma eğilimindeyim. AnyCPU'da inşa edeceğimiz 64bit makineler için performans daha iyi olsa da güvenilirlik bizim için daha önemli.
Tüm bileşenlerinizi 32bit (x86) olarak oluşturmayı denemenizi öneririm, gerçekten yoğun şeyler yapmadığınız sürece çok fazla fark yaratacağından şüpheliyim.