【问题标题】:BadImageFormatException. This will occur when running in 64 bit mode with the 32 bit Oracle client components installed坏图像格式异常。这将在安装了 32 位 Oracle 客户端组件的 64 位模式下运行时发生
【发布时间】:2014-07-29 01:04:39
【问题描述】:

当我的 .Net 应用程序尝试连接到 oracle 数据库时,我收到此错误。

错误提示This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.But I have made sure 很多时候客户端安装在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)

【问题讨论】:

  • 您使用的是System.Data.OracleClient。这个命名空间has been deprecated and will be removed in a future version of .NET。也许您正在使用它的 32 位版本?它也不是 Oracle 客户端的一部分,因此无论您使用的是 32 位还是 64 位 Oracle 客户端都无关紧要。理想情况下,您应该改用Oracle.DataAccess(或Oracle.ManagedDataAccess)。
  • 小错误:System.Data.OracleClient 只是提供者,它还使用了必须与架构匹配的 Oracle 客户端。只有Oracle.ManagedDataAccess 不需要安装额外的Oracle 客户端。也许 Oracle 客户端是 x64,但您的应用程序是 32 位的,这也不起作用。可以在同一台机器上同时安装 32 位和 64 位 Oracle 客户端

标签: .net oracle oracle11g


【解决方案1】:

一种解决方案是在您的计算机上同时安装 x86(32 位)和 x64 Oracle 客户端,那么您的应用程序在哪个架构上运行并不重要。

这里是在一台机器上安装 x86 和 x64 Oracle 客户端的说明:

假设:Oracle Home 名为 OraClient11g_home1,客户端版本为 11gR2

  • 可选择删除任何已安装的 Oracle 客户端(如果遇到问题,请参阅 How to uninstall / completely remove Oracle 11g (client)?

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

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

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

  • 更改到文件夹 %WINDIR%\SysWOW64(通常是 C:\Windows\SysWOW64)并创建符号链接 ora112 到文件夹 C:\Oracle\11.2\Client_x86,(见下文)

  • 修改PATH 环境变量,将C:\Oracle\11.2\Client_x86C:\Oracle\11.2\Client_x64 等所有条目替换为C:\Windows\System32\ora112,分别对应它们的\bin 子文件夹。注意:C:\Windows\SysWOW64\ora112 不能在 PATH 环境中。

  • 如果需要,请将您的 ORACLE_HOME 环境变量设置为 C:\Windows\System32\ora112

  • 打开您的注册表编辑器。将注册表值HKLM\Software\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME 设置为C:\Windows\System32\ora112

  • 将注册表值HKLM\Software\Wow6432Node\ORACLE\KEY_OraClient11g_home1\ORACLE_HOME 设置为C:\Windows\System32\ora112(不是C:\Windows\SysWOW64\ora112

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

  • 将您的TNS_ADMIN 环境变量(分别在注册表中的TNS_ADMIN 条目)设置到一个公共位置可能是一个明智的选择,例如TNS_ADMIN=C:\Oracle\Common\network

创建符号链接的命令:

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.

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

【讨论】:

  • 运行 Oracle 客户端安装程序时,它会要求您提供 Oracle Base 的路径和 Oracle Home 的路径。在此处的说明中,您是否只需将“OraClient11g_home1”添加到您指定的每个路径?所以 Oracle Base 应该是“C:\Oracle\11.2\Client_x86”,而软件位置(Oracle Home)应该是“C:\Oracle\11.2\Client_x86\OraClient11g_home1”?
  • OraClient11g_home1 是“Oracle Home Name”,用于识别注册表中的正确键,请参阅How Home Selector Works。在早期的 Oracle 版本中,您有一个“Oracle Home Selector”应用程序,您可以在其中在一台机器上安装的不同 Oracle 客户端之间切换。 Oracle Home Name 不必与安装 Oracle 的文件夹名称相同。 Oracle Base "C:\Oracle\11.2\Client_x86" 和软件位置 "C:\Oracle\11.2\Client_x86\OraClient11g_home1" 工作正常。
  • 啊,我明白了... Instant Client 只要求您提供一条路径:软件位置,即 Oracle 主目录。因此,您上面的所有路径都是 Oracle Home。如果您选择其他三种安装类型(管理员、运行时、自定义)中的任何一种,它会让您选择 Oracle Base 和 Oracle Home 的路径。如果我为我的 Oracle Home 选择“C:\Oracle\11.2\Client_x86\OraClient11g_home1”,那么我需要使用该路径代替上面的路径...
  • 这很有帮助。 64 位 xCopy 软件包是否足够好,还是需要完整的 64 位客户端?除了 instaclient,我似乎找不到它的下载,但我没有安装 32bit instaclient,而是完整的客户端。
  • 我应该澄清我的最后评论。在 .net 应用程序与 oracle 提供者连接的上下文中,有人显然是连接到 oracle 的新手,我想我想我想知道为什么你会经历所有这些,而不是仅仅在 .config 文件中设置 dllpath?最后我只会发布我自己的答案,但既然你有接受的答案,我想展示一下讨论。
【解决方案2】:

我在 Windows 10 电脑上遇到了同样的问题。我将项目从旧计算机复制到新计算机,均为 64 位,并在新计算机上安装了 64 位 Oracle 客户端。我得到了同样的错误信息,但是在尝试了很多没有效果的解决方案之后,对我来说真正有用的是: 在您的 Visual Studio(我的是 2017 年)中转到 工具 > 选项 > 项目和解决方案 > Web 项目

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

【讨论】:

  • 这对我也有用。默认情况下,IIS express 将在 VS 中以 32 位模式运行。
【解决方案3】:

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

我的解决方案:在分配给我的 ASP.NET 应用程序的 应用程序池 的高级设置中,我设置了 Enable 32 -Bit ApplicationsTrue

请参阅下面的独立 .ashx 测试脚本,我用于测试连接到 Oracle 的能力。在更改应用程序池之前,它的响应是:

[Running as 64-bit] Connection failed.

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

[Running as 32-bit] Connection succeeded.

TestOracle.ashx – 通过 System.Data.OracleClient 测试 Oracle 连接的脚本:

使用方法:根据需要更改用户、密码和主机变量。

请注意,此脚本可以以独立方式使用,而不会影响您的 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;
    }
}

【讨论】:

    【解决方案4】:

    修改IIS

    1. 选择应用程序池。
    2. ASP .NET V4.0 Classic 中的 Clic。
    3. 选择高级设置。
    4. 一般情况下,启用 32 位应用程序选项,默认为 false。选择 TRUE。
    5. 刷新并检查网站。

    评论:

    平台:Windows Server 2008 R2 Enterprise - 64Bit - IIS 7.5

    【讨论】:

      【解决方案5】:

      正如 cmets 中所指出的,System.Data.OracleClient 已被弃用。没有什么理由在游戏这么晚才开始使用它。

      正如 cmets 中所指出的(我已将其标记为社区 wiki 以供观察),现在有一个托管提供程序作为 odp.net 包的 12c 和更高版本的一部分。此提供程序不需要任何非托管 dll,因此在这种情况下这应该不是问题。

      如果您希望使用 oracle 中旧的非托管 Oracle.DataAccess 提供程序,最简单的解决方案是设置“DllPath”配置变量:

      <?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 中的“非托管 DLL 的搜索顺序”

      【讨论】:

      • 这里有一个更新,因为 VS2015 和 Oracle 12cR3 已经出...如果你想同时安装 32 位和 64 位客户端,请下载两个 ODAC 包(我花了一段时间才找到它们,但只需搜索“oracle 64 bit odac”等)。将它们中的每一个安装到“C:\Oracle\12.1.0.2.1\”的 Oracle Base 路径,然后为软件位置添加“\Client_x86”(或 x64)到该路径。 b_levitt 所说的一切都适用。两个版本都是完全配置的,32 位应用程序将使用 32 位驱动程序,而 64 位应用程序将使用 64 位驱动程序。简单易懂。
      • 哦,截至 2015 年 9 月 4 日,Oracle 仍未发布适用于 Visual Studio 2015 的 Oracle 开发人员工具。他们承诺会在 VS2015 RTM 的一个月内发布,但已经过去了那仍然没有出现。 :(
      【解决方案6】:

      这个解决方案对我有用,

      修改 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 Standart- 64Bit - IIS 8

      【讨论】:

        【解决方案7】:

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

        为了简短起见,它说:(如果页面仍然存在,只需转到该页面并按照说明进行操作......) 1) 从 oracle 站点下载并安装最新版本的 odac 64 位 xcopy。 2) 从 oracle 站点下载并安装最新版本的 odac 32 位 xcopy。 如何?以管理员身份打开 cmd shell 并运行: c:\64bitODACLocation> install.bat oledb c:\odac\odac64. 第一个参数是您要安装的组件。第二个参数是安装到哪里。 像这样安装 32 版本:c:\32bitODACLocation> install.bat oledb c:\odac\odac32。 3) 将系统路径更改为包含c:\odac\odac32; c:\odac\odac32\bin; c:\odac\odac64;c:\odac\odac64\bin 按此顺序。 4) 重启机器。 5) 确保您在 odac32\admin\network 和 odac64\admin\network 文件夹中具有相同的 tnsnames.ora(或至少相同的连接条目)。 6) 现在在 Visual Studio 中打开 SSIS(我使用了带有 ssis 包的免费 2013 版本) - 使用 OLEDB,然后选择 Oracle Provider for OLE DB provider 作为连接类型。将 tnsnames.ora 中的条目名称设置为“服务器或文件名”。用户名是您的架构名称(数据库名称),密码是架构的密码。你完成了!

        同样,您可以在原始网站中找到非常详细的解决方案以及更多内容。

        这是唯一对我有用并且没有弄乱我的环境的东西。

        干杯! gcr

        【讨论】:

        • 请描述(用你自己的话)说明告诉你做什么。您链接到的页面很容易消失,然后我们仍然不知道如何解决此错误。
        【解决方案8】:

        我使用带有 2.0 框架的 C#.net 以及用于连接 oracle db 的 system.data.oracleclient 开发了桌面应用程序,我遇到了类似的错误消息,“尝试加载 Oracle 客户端库抛出 BadImageFormatException。运行时会出现此问题安装了 32 位 Oracle 客户端组件的 64 位模式。"

        应用了以下解决方案

        • 项目,属性,构建选项卡,选择平台目标:x86
        • 项目、干净构建、重建解决方案
        • 安装Oracle 11G*32位客户端

        现在,它可以工作了,因为应用程序设置为 32 位,并且安装在 Win2012 R2 服务器上的 oracle 32 位客户端,希望对您有用。

        【讨论】:

          【解决方案9】:

          我在 Windows 2012 R2 上安装的 DNN 应用程序中出现此错误。它使用一些 32 位 dll 并且只有 Oracle.DataAccess.dll x32 工作。我的解决方案是:

          1. 卸载旧的 Oracle 客户端 \ODAC。
          2. 安装 Oracle 11 客户端 x32。
          3. 安装 Oracle ODAC 12 x64。
          4. 检查 IIS 应用程序池(经典版)是否有“启用 32 位应用程序”选项 = true。

          【讨论】:

            【解决方案10】:

            在您正在使用的 IIS 应用程序池中将 Enable32bit 应用程序设为 TRUE

            【讨论】:

            • 把这个扔掉,以防有人遇到这个问题。在我的情况下,应用程序池的 32 位设置为 True。我必须将其设置为 False 才能让我的工作,但它是应用程序池。
            【解决方案11】:

            我遇到了同样的问题,然后我通过更改配置管理器 x86 -> x64 并构建来修复它

            【讨论】:

              【解决方案12】:

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

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

              我建议尝试在 32 位 (x86) 中构建所有组件,除非你正在做一些非常密集的事情,我怀疑它会产生很大的不同。

              【讨论】:

                【解决方案13】:

                正如 apc 提到的那样,“当 32 位 dll 调用 64 位 dll 时发生错误,反之亦然”。问题是,如果您使用 AnyCPU 构建并在 64 位环境中运行,那么应用程序将以 64 位运行。 如果无法为 32 位和 64 位显式重建,那么您可以使用 Windows SDK 附带的名为 corflags.exe 的 Microsoft 实用程序。基本上,您可以在正在执行的程序的 exe 中修改一个标志,以告诉它以 32 位运行,即使环境是 64 位。

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

                【讨论】:

                  【解决方案14】:

                  我想添加一个对我有用的解决方案。 设置:在 Windows 2008 R2(64 位操作系统)上运行的 Oracle 11g 64 位

                  客户端是使用 x86 平台设置编译的 .net framework 3.5 应用程序(从 2.0 移植)。

                  我遇到了完全相同的 BadImageFormatException 问题。编译为 64 位消除了异常,但它不是我的选择,因为我的应用程序使用的是 32 位 activex 组件,这些组件在 64 位中不起作用。

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

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

                  这可能可以通过更改上述建议的环境设置来完成,但这种方法的优点是不会更改服务器配置上的任何设置。

                  【讨论】:

                    【解决方案15】:

                    我的是控制台应用程序(它也应该适用于 Windows 应用程序),我也遇到了同样的问题。 为了解决这个问题,我将 PlatformTarget 用作 x64,因为我的 System.Data.OracleClient.dll(64 位文件)位于 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5。这将显式使用 64 位版本的 Oracle 客户端。 如果您的解决方案仅适用于 64 位并且您不使用 32 位 dll(如 VB 中制作的 dll),这可能会对您有所帮助。 希望对你有帮助。

                    【讨论】:

                      【解决方案16】:

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

                      【讨论】:

                        【解决方案17】:

                        我也遇到了同样的错误,我检查了我的系统是 64 位的,我使用的是 32 位版本的 oracle.DataAccess 我添加了正确的 64 位版本,现在它得到了解决 下面是 Oracle.DataAccess.dll 的引用路径

                        64 位操作系统的正确路径-C:\Oracle\11g_64\product\11.2.0\client_64\odp.net\bin\4\Oracle.DataAccess.dll

                        32 位操作系统的正确路径-C:\Oracle\11g_32\product\11.2.0\client_64\odp.net\bin\4\Oracle.DataAccess.dll

                        【讨论】:

                          【解决方案18】:

                          我在控制台应用程序中遇到了这个问题。

                          在我的情况下,我只是将 Platform Target 更改为“Any CPU”,当您右键单击解决方案并单击属性时,您会看到它,您会发现Tab "Build" 点击它,你会看到 "Platform target:" 把它改成 "Any CPU",这样就可以解决你的问题了

                          【讨论】:

                            【解决方案19】:

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

                            【讨论】:

                              【解决方案20】:

                              对于 ssis 2008,只需激活 32 位运行,如下图(点击此链接)

                              【讨论】:

                                【解决方案21】:

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

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2013-05-08
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2014-05-16
                                  • 2020-11-19
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多