BadImageFormatException。 在安装了32位Oracle客户端组件的64位模式下运行时会发生这种情况

我得到这个错误,而我的.Net应用程序正试图build立一个连接到Oracle数据库。

错误表示This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed. 。 但是我已经确定很多次,安装在x64位的客户端不是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) 

一种解决scheme是在您的机器上安装x86(32位)和x64 Oracle客户机,然后在您的应用程序正在运行的架构上无关紧要。

这里有一条在一台机器上安装x86和x64 Oracle客户机的指令:

假设: Oracle Home被称为OraClient11g_home1 ,客户端版本是11gR2

  • 可以select删除已安装的Oracle客户端

  • 下载并安装Oracle x86 Client,例如到C:\Oracle\11.2\Client_x86

  • 将Oracle x64 Client下载并安装到不同的文件夹 ,例如C:\Oracle\11.2\Client_x64

  • 打开命令行工具,转到文件夹%WINDIR%\ System32,通常是C:\Windows\System32并创build一个符号链接ora112到文件夹C:\Oracle\11.2\Client_x64 (见下文)

  • 切换到文件夹%WINDIR%\ SysWOW64,通常是C:\Windows\SysWOW64并创build一个符号链接ora112到文件夹C:\Oracle\11.2\Client_x86 (见下文)

  • 修改PATH环境variables,将C:\Oracle\11.2\Client_x86C:\Oracle\11.2\Client_x64等所有条目分别replace为C:\Windows\System32\ora112和它们的\bin子文件夹。 注意: C:\Windows\SysWOW64\ora112不得在PATH环境中。

  • 如果需要,将ORACLE_HOME环境variables设置为C:\Windows\System32\ora112

  • 打开registry编辑器。 将registry值HKLM\Software\ORACLE\KEY_OraClient11g_home1\ORACLE_HOMEC:\Windows\System32\ora112

  • 将registry值HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOMEC:\Windows\System32\ora112 (不是C:\Windows\SysWOW64\ora112

  • 你完成了! 现在,您可以将x86和x64 Oracle客户端无缝地结合在一起,即一个x86应用程序将加载x86库,一个x64应用程序加载x64库,而无需对系统进行任何修改。

  • TNS_ADMIN环境variables(registry中的TNS_ADMIN条目)设置为一个公共位置(例如TNS_ADMIN=C:\Oracle\Common\network )可能是明智的select。

创build符号链接的命令:

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

笔记:

两个符号链接必须具有相同的名称,例如ora112

尽pipe名称文件夹C:\Windows\System32包含x64库,而C:\Windows\SysWOW64包含x86(32位)库。 不要混淆。

在我的情况下,Oracle 11.2 32位客户端安装在我的64位Windows 2008 R2操作系统上。

我的解决scheme:在分配给我的ASP.NET应用程序的“ 应用程序池 ”的“高级设置”中,将“ 启用32位应用程序”设置为“ True”

请参阅下面的文章 ,了解我用来testing连接Oracle的能力的独立.ashxtesting脚本。 在进行应用程序池更改之前,其响应是:

 [Running as 64-bit] Connection failed. 

…在应用程序池更改之后:

 [Running as 32-bit] Connection succeeded. 

TestOracle.ashx – 通过System.Data.OracleClienttestingOracle连接的脚本:

使用:根据需要更改用户,密码和主机variables。

请注意,此脚本可以独立使用而不会干扰您的ASP.NET Web应用程序项目文件。 把它放在你的应用程序文件夹中。

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

修改IIS

  1. select应用程序池。
  2. 在ASP .NET V4.0 Classic中使用Clic。
  3. select高级设置。
  4. 通常情况下,选项启用32位应用程序,默认为false。 selectTRUE。
  5. 刷新并检查网站。

评论:

平台:Windows Server 2008 R2企业版 – 64位 – IIS 7.5

正如在注释中指出的那样,System.Data.OracleClient已被弃用。 没有什么理由在这么晚的时候开始使用它。

另外正如评论中所指出的那样(我已经在观察中将其标记为社区wiki),现在有一个托pipe提供者作为odp.net包的12c及更高版本的一部分。 这个提供程序不需要任何非托pipedll,所以在这种情况下这应该不是问题。

如果您更喜欢使用Oracle的旧的非托pipeOracle.DataAccess提供程序,最简单的解决scheme是设置“DllPath”configurationvariables:

 <?xml version="1.0" encoding="utf-8" ?> <configuration> <oracle.dataaccess.client> <add key="DllPath" value="C:\oracle\bin"/> </oracle.dataaccess.client> </configuration> 

有关详细信息,请参阅http://docs.oracle.com/database/121/ODPNT/InstallODP.htm中的“非托pipeDLL的search顺序”。;

我在SSIS 2008中遇到了同样的问题。我尝试使用ODAC 12c 32位连接到Oracle 11g。 试图安装ODAC 12C 64位以及。 SSIS实际上是能够预览表,但是当试图运行该包时它给出了这个错误消息。 没有帮助。 切换到VS 2013,现在它在debugging模式下运行,但使用dtexec / f文件名运行包时得到相同的错误。 然后我发现这个网页: http : //sqlmag.com/comment/reply/17881 。

简单的说:(如果页面仍然存在,只需进入页面并按照说明操作)。1)从oracle站点下载并安装最新版本的odac 64位xcopy。 2)从oracle站点下载并安装最新版本的odac 32位xcopy。 怎么样? 打开cmd shell作为ADMINSTARTOR并运行:c:\ 64bitODACLocation> install.bat oledb c:\ odac \ odac64。 第一个参数是你想要安装的组件。 第二个参数是安装到哪里。 安装32版本,就像这样:c:\ 32bitODACLocation> install.bat oledb c:\ odac \ odac32。 3)更改系统的path以包含c:\ odac \ odac32; C:\ ODAC \ odac32 \ BIN; c:\ odac \ odac64; c:\ odac \ odac64 \ bin在这个命令。 4)重新启动机器。 5)确保在odac32 \ admin \ network和odac64 \ admin \ network文件夹(或者至less是连接的相同条目)中都有相同的tnsnames.ora。 6)现在在Visual Studio中打开SSIS(我使用ssis包的免费2013版本) – 使用OLEDB,然后selectOracle Provider for OLE DB提供程序作为连接types。 将tnsnames.ora中条目的名称设置为“服务器或文件名”。 用户名是您的架构名称(数据库名称),密码是架构的密码。 你完成了!

再次,你可以find非常详细的解决scheme,更在原来的网站。

这是唯一为我工作,并没有弄乱我的环境。

干杯! GCR

BadImageFormatException发生在32位(x86)dll调用64位dll时,反之亦然。 如果使用AnyCPU作为您的条目可执行文件,那么在64位计算机上运行时,它将以64位运行,但是如果那样会调用32位dll,则会出现exception,这就是为什么AnyCPU并不总是答案。

我倾向于将所有内容都构build为32位(x86),因为我们仍然需要与在VB6(32位(x86))中完成的一些旧组件进行接口。 如果我们在哪里build立AnyCPU可靠性对于我们来说更重要,那么64位机器的性能可能会更好。

我会build议试图build立在32位(x86)的所有组件,除非你正在做一些真正的密集的东西,我怀疑它会有很大的不同。

正如apc提到的错误发生时“当一个32位DLL调用一个64位的DLL或反之亦然”。 问题是,如果你使用AnyCPU构build,并运行在64位环境,那么应用程序将运行为64位。 如果显式重build32和64位不是一个选项,那么你可以使用Windows SDK附带的一个名为corflags.exe的微软实用程序。 基本上,你可以在正在执行的程序的exe文件中修改一个标志,告诉它以32位运行,即使环境是64位。

有关使用它的信息,请参阅此处

我想添加一个解决scheme,为我工作。 安装:在Windows 2008 R2(64位操作系统)上运行的Oracle 11g 64位

客户端是一个.NET平台3.5应用程序(从2.0移植)与x86平台设置编译。

我有完全相同的问题BadImageFormatException。 编译为64位消除了exception,但它不是我的select,因为我的应用程序正在使用64位不工作的32位ActiveX组件。

我通过从Oracle网站下载Oracle Instant Client 11(这只是一堆DLL而不是xcopied)来解决这个问题,并将这些文件复制到我的应用程序文件目录中。 请参阅: http : //www.oracle.com/technetwork/database/features/oci/instant-client-wp-131479.pdf

这已经解决了这个问题,从ProcMon工具,我可以看到,本地复制oci.dll得到由System.Data.OracleClient加载,一切都很好。

这可能可以通过改变上面提出的环境设置来完成,但是这种方法的优点是不会改变服务器configuration上的任何设置。

我有一个控制台应用程序的这个问题。 在我的情况下,我只是将平台目标更改为“任何CPU”,你可以看到当你右键点击你的解决scheme,并点击属性,你会发现一个选项卡“生成”点击它,你会看到“平台目标:”改变它到“任何CPU”,这将解决您的问题

这个解决scheme适合我,

修改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. 

评论:

平台:Windows Server 2012标准版 – 64位 – IIS 8

我的控制台应用程序(它也应该为Windows应用程序工作),我也有同样的问题。 为了解决这个问题,我使用了PlatformTarget作为x64,因为我的System.Data.OracleClient.dll(64位文件)位于C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.5。 这将明确使用64位版本的Oracle客户端。 这可能会帮助你,如果你的解决scheme只适用于64位,如果你不使用32位DLL如在VB中制作的DLL。 我希望这会帮助你。

我在Windows 10 PC上遇到了同样的问题。 我将项目从旧计算机复制到新的64位,并在新机器上安装了Oracle客户端64位。 我得到了同样的错误信息,但在尝试了许多解决scheme后无效,实际上我的工作是这样的:在你的Visual Studio(我的是2017)去工具>选项>项目和解决scheme> Web项目

在该页面上,检查以下选项:使用IIS Express的64位版本进行网站和项目

请下载正确版本的Oracle Client,如Oracle Client 11.2 32位; 这解决了我的问题。

确保registryHKEY_LOCAL_MACHINE \ SOFTWARE \ ORACLE \ ODP.NET \ 4.112。#DIIPATH键指向32位Oarcle客户端BIN目录。 例如,DIIPath值可以是C:\ app \ User_name \ 11.2.0 \ client_32bit \ bin

只需在x86模式下构build你的代码,而不是在AnyCpu中。