BadImageFormatException. Ciò si verifica quando si esegue in modalità 64 bit con i componenti client Oracle a 32 bit installati

Sto ottenendo questo errore mentre sul mio. .Net applicazione stanno cercando di fare una connessione al database Oracle.

L’errore indica che This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed. . Ma ho fatto in modo che molte volte il client fosse installato su x64 bit e non su 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 soluzione consiste nell’installare entrambi i client Oracle x86 (32-bit) e x64 sulla macchina, quindi non importa su quale architettura è in esecuzione l’applicazione.

Ecco una istruzione per installare il client Oracle x86 e x64 su una macchina:

Presupposti: Oracle Home si chiama OraClient11g_home1 , la versione client è 11gR2

  • Rimuovere facoltativamente qualsiasi client Oracle installato (vedere Come disinstallare / rimuovere completamente Oracle 11g (client)? Se si incontrano problemi)

  • Scarica e installa Oracle x86 Client, ad esempio in C:\Oracle\11.2\Client_x86

  • Scarica e installa Oracle x64 Client in una cartella diversa , ad esempio in C:\Oracle\11.2\Client_x64

  • Apri lo strumento da riga di comando, vai alla cartella% WINDIR% \ System32, in genere C:\Windows\System32 e crea un collegamento simbolico ora112 alla cartella C:\Oracle\11.2\Client_x64 (vedi la sezione comandi sotto)

  • Passare alla cartella% WINDIR% \ SysWOW64, in genere C:\Windows\SysWOW64 e creare un collegamento simbolico ora112 nella cartella C:\Oracle\11.2\Client_x86 , (vedi sotto)

  • Modificare la variabile di ambiente PATH , sostituire tutte le voci come C:\Oracle\11.2\Client_x86 e C:\Oracle\11.2\Client_x64 di C:\Windows\System32\ora112 , rispettive rispettive sottocartelle \bin . Nota: C:\Windows\SysWOW64\ora112 non deve essere nell’ambiente PATH.

  • Se necessario, imposta la tua variabile d’ambiente ORACLE_HOME su C:\Windows\System32\ora112

  • Apri l’editor del registro. Imposta il valore del Registro di sistema HKLM\Software\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME in C:\Windows\System32\ora112

  • Imposta il valore del Registro di sistema HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME in C:\Windows\System32\ora112 (non C:\Windows\SysWOW64\ora112 )

  • Hai fatto! Ora è ansible utilizzare senza problemi il client Oracle x86 e x64, ovvero un’applicazione x86 carica le librerie x86, un’applicazione x64 carica le librerie x64 senza ulteriori modifiche sul sistema.

  • Probabilmente è una saggia opzione per impostare la variabile di ambiente TNS_ADMIN ( TNS_ADMIN voci TNS_ADMIN nel Registro di sistema) in un percorso comune, ad esempio TNS_ADMIN=C:\Oracle\Common\network .

Comandi per creare collegamenti simbolici:

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

Gli appunti:

Entrambi i collegamenti simbolici devono avere lo stesso nome, ad esempio ora112 .

Nonostante la loro cartella dei nomi C:\Windows\System32 contenga le librerie x64, mentre C:\Windows\SysWOW64 contiene le librerie x86 (a 32 bit). Non essere confuso.

Nella mia situazione, il client Oracle 11.2 a 32 bit è stato installato sul mio sistema operativo Windows 2008 R2 a 64 bit .

La mia soluzione: nelle Impostazioni avanzate per il pool di applicazioni assegnate alla mia applicazione ASP.NET , ho impostato Abilita applicazioni a 32 bit su True .

Si prega di vedere sotto per lo script di test .ashx standalone che ho usato per testare la possibilità di connettersi a Oracle. Prima di modificare il pool di applicazioni, la sua risposta è stata:

 [Running as 64-bit] Connection failed. 

… e dopo la modifica del pool di applicazioni:

 [Running as 32-bit] Connection succeeded. 

TestOracle.ashx – Script per testare una connessione Oracle tramite System.Data.OracleClient:

Per utilizzare: modificare l’utente, la password e le variabili host in modo appropriato.

Si noti che questo script può essere utilizzato in modo autonomo senza disturbare il file di progetto dell’applicazione Web ASP.NET. Basta rilasciarlo nella cartella dell’applicazione.

 <%@ 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; } } 

Ho avuto lo stesso problema su un PC Windows 10. Ho copiato il progetto dal mio vecchio computer a quello nuovo, entrambi a 64 bit, e ho installato l’Oracle Client 64 bit sulla nuova macchina. Ho ricevuto lo stesso messaggio di errore, ma dopo aver provato molte soluzioni senza alcun effetto, ciò che effettivamente ha funzionato per me è stato questo: nel tuo Visual Studio (il mio è il 2017) vai su Strumenti> Opzioni> Progetti e soluzioni> Progetti web

In questa pagina, seleziona l’opzione che dice: Usa la versione a 64 bit di IIS Express per siti web e progetti

Per rivedere IIS

  1. Seleziona i pool di applicazioni.
  2. Clic in ASP .NET V4.0 Classic.
  3. Seleziona Impostazioni avanzate.
  4. In generale, l’opzione Abilita applicazioni a 32 bit, l’impostazione predefinita è false. Seleziona VERO.
  5. Aggiorna e controlla il sito.

Commento:

Piattaforma: Windows Server 2008 R2 Enterprise – 64 Bit – IIS 7.5

Come è stato sottolineato nei commenti, System.Data.OracleClient è deprecato. Ci sono pochi motivi per iniziare a usarlo così tardi nel gioco.

Inoltre, come indicato nei commenti (che ho contrassegnato come wiki della comunità in osservanza), ora c’è un provider gestito come parte delle versioni 12c e successive del pacchetto odp.net. Questo provider NON richiede alcuna DLL non gestita, quindi in questo caso non dovrebbe essere un problema.

Se si preferisce utilizzare il vecchio provider Oracle.DataAccess non gestito da Oracle, la soluzione più semplice è impostare la variabile di configurazione “DllPath”:

       

Vedere “Ordine di ricerca per DLL non gestite” in http://docs.oracle.com/database/121/ODPNT/InstallODP.htm per ulteriori informazioni

Ho avuto lo stesso problema in SSIS 2008. Ho provato a connettermi a Oracle 11g usando ODAC 12c a 32 bit. Ho cercato di installare ODAC 12c anche a 64 bit. SSIS era effettivamente in grado di visualizzare l’anteprima della tabella, ma quando cercava di eseguire il pacchetto stava dando questo messaggio di errore. Niente ha aiutato. Passato a VS 2013, ora era in esecuzione in modalità di debug, ma ha ottenuto lo stesso errore quando si eseguiva il pacchetto usando dtexec / f nomefile. Poi ho trovato questa pagina: http://sqlmag.com/comment/reply/17881 .

Per farla breve dice: (se la pagina è ancora lì basta andare alla pagina e seguire le istruzioni …) 1) Scaricare e installare l’ultima versione di odac 64 bit xcopy dal sito di Oracle. 2) Scaricare e installare l’ultima versione di odac 32 bit xcopy dal sito di Oracle. Come? aprire una shell CMD COME UN ADMINSTARTOR ed eseguire: c: \ 64bitODACLocation> install.bat oledb c: \ odac \ odac64. il primo parametro è il componente che si desidera installare. Il secondo parametro è dove installare. installa anche la versione 32 in questo modo: c: \ 32bitODACLocation> install.bat oledb c: \ odac \ odac32. 3) Modificare il percorso del sistema per includere c: \ odac \ odac32; c: \ ODAC \ odac32 \ bin; c: \ odac \ odac64; c: \ odac \ odac64 \ bin IN QUESTO ORDINE. 4) Riavvia la macchina. 5) assicurati di avere lo stesso tnsnames.ora nelle cartelle odac32 \ admin \ network e odac64 \ admin \ network (o almeno la stessa voce per la tua connessione). 6) Ora apri SSIS in Visual Studio (ho utilizzato la versione 2013 gratuita con il pacchetto ssis): utilizza OLEDB e quindi seleziona il provider Oracle per provider OLE DB come tipo di connessione. Imposta il nome della voce nel tuo tnsnames.ora come “nome del server o del file”. Il nome utente è il nome dello schema (nome db) e la password è la password per lo schema. hai fatto!

Ancora una volta, è ansible trovare la soluzione molto dettagliata e molto altro nel sito originale.

Questa era l’unica cosa che funzionava per me e non rovinava il mio ambiente.

Saluti! GCR

Ho sviluppato un’applicazione desktop utilizzando C # .net con framework 2.0 insieme a system.data.oracleclient per la connessione di Oracle db e mi trovavo di fronte a un messaggio di errore simile: “Tentativo di caricare le librerie client Oracle ha generato BadImageFormatException. Questo problema si verificherà durante l’esecuzione in modalità 64 bit con i componenti client Oracle a 32 bit installati. ”

sono state applicate le seguenti soluzioni

  • Progetto, proprietà, Crea TAB, seleziona target della piattaforma: x86
  • Progetto, clean build, soluzione ReBuild
  • Installa il client Oracle 11G * a 32 bit

ora funziona perché l’applicazione è impostata per 32 bit e il client oracle 32 bit installato su server Win2012 R2, si spera funzionerà per voi.

BadImageFormatException si verifica quando una dll 32 bit (x86) chiama una dll a 64 bit o viceversa. Se si utilizza AnyCPU per l’eseguibile della voce, quando viene eseguito su una macchina a 64 bit verrà eseguito a 64 bit, tuttavia se si chiama una dll a 32 bit si ottiene l’eccezione, motivo per cui AnyCPU non è sempre la risposta.

Tendo a build tutto come 32 bit (x86) perché dobbiamo ancora interfacciare con alcuni vecchi componenti fatti in VB6 (32 bit (x86)). Mentre le prestazioni potrebbero essere migliori per le macchine a 64 bit, se noi dovessimo creare l’affidabilità AnyCPU è più importante per noi.

Vorrei suggerire di provare a build tutti i componenti in 32 bit (x86), a meno che non si stiano facendo cose davvero intensive, dubito che farà molta differenza.

Come apc ha detto che l’errore si verifica “quando una dll a 32 bit chiama una dll a 64 bit o viceversa”. Il problema è che se hai costruito usando AnyCPU e sei in esecuzione su un ambiente a 64 bit, l’applicazione funzionerà come 64 bit. Se la ricostruzione esplicita per 32 e 64 bit non è un’opzione, è ansible utilizzare un’utilità Microsoft denominata corflags.exe fornita con Windows SDK. Fondamentalmente, puoi modificare un flag nel file exe del programma che stai eseguendo per dirgli di funzionare come 32bit anche se l’ambiente è a 64 bit.

Vedi qui per informazioni su come usarlo

Vorrei aggiungere una risoluzione che ha funzionato per me. Installazione: Oracle 11g 64 bit in esecuzione su Windows 2008 R2 (sistema operativo a 64 bit)

Client è un’applicazione .net framework 3.5 (con porta 2.0) compilata con l’impostazione della piattaforma x86.

Ho avuto esattamente lo stesso problema di BadImageFormatException. La compilazione a 64 bit elimina l’eccezione, ma per me non era un’opzione perché la mia app utilizza componenti activex a 32 bit che non funzionano a 64 bit.

Ho risolto il problema scaricando Oracle Instant Client 11 (questo è solo un mucchio di DLL che può essere xcopied) dal sito Web di Oracle e copiando i file nella directory dei file dell’applicazione. Vedi qui: http://www.oracle.com/technetwork/database/features/oci/instant-client-wp-131479.pdf

Questo ha risolto il problema, dallo strumento ProcMon posso vedere che oci.dll copiato localmente viene caricato da System.Data.OracleClient e tutto va bene.

Potrebbe probabilmente essere fatto modificando le impostazioni dell’ambiente come proposto sopra, ma questo metodo ha il vantaggio di non alterare alcuna impostazione sulla configurazione del server.

Ho ottenuto questo problema per un’applicazione console. Nel mio caso ho appena cambiato Platform Target in “Any CPU” che puoi vedere quando fai clic con il tasto destro del mouse sulla tua soluzione e fai clic su Proprietà, troverai una scheda “Build” fai clic su di essa vedrai “Target della piattaforma:” cambiala a “Qualsiasi CPU”, che risolverà il tuo problema

questa soluzione funziona per me,

Per rivedere IIS

 Select Application Pools. Clic in ASP .NET V4.0 Classic. Select Advanced Settings. In General, option Enable 32-Bit Applications, default is false. Select TRUE. Refresh and check site. 

Commento:

Piattaforma: Windows Server 2012 Standart – 64 Bit – IIS 8

La mia è l’applicazione console (dovrebbe funzionare anche per l’applicazione Windows) e ho avuto lo stesso problema. Per risolverlo ho usato PlatformTarget come x64 mentre il mio System.Data.OracleClient.dll (file a 64 bit) si trova in C: \ Programmi (x86) \ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.5. Questo utilizzerà esplicitamente la versione a 64 bit di Oracle Client. Questo potrebbe aiutarti se la tua soluzione funziona solo su 64 bit e se non stai usando dll a 32 bit come le DLL fatte in VB. Spero ti possa aiutare.

Si prega di scaricare la versione corretta di Oracle Client come Oracle Client 11.2 a 32 bit; che ha risolto il problema per me.

Assicurarsi che la chiave di registro HKEY_LOCAL_MACHINE \ SOFTWARE \ ORACLE \ ODP.NET \ 4.112. # DIIPath stia puntando alla directory BIN del client Oarcle a 32 bit. Ad esempio, il valore DIIPath può essere C: \ app \ nome_utente \ 11.2.0 \ client_32bit \ bin

Costruisci il tuo codice in modalità x86 non in AnyCu.