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

时间:2014-06-08 08:10:27

标签: .net oracle oracle11g

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

错误表示This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.x64安装在[{1}}的客户端多次But I have made sure而不是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)

21 个答案:

答案 0 :(得分:44)

一种解决方案是在您的计算机上安装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(请参阅下面的命令部分)< / p>

  • 更改为文件夹%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位)库。不要困惑。

答案 1 :(得分:11)

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

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

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

[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;
    }
}

答案 2 :(得分:7)

我在Windows 10 PC上遇到了同样的问题。我将项目从旧计算机复制到新计算机,均为64位,并在新计算机上安装了Oracle Client 64位。我得到了相同的错误消息,但在尝试了许多解决方案后没有效果,实际上对我有用的是: 在你的Visual Studio(我的是2017年)去 工具&gt;选项&gt;项目和解决方案&gt;网络项目

在该页面上,选中以下选项: 使用64位版本的IIS Express for Websites and Projects

答案 3 :(得分:2)

正如评论中指出的那样,不推荐使用System.Data.OracleClient。没有理由在比赛的最后阶段开始使用它。

正如评论中指出的那样(我在观察中将其标记为社区维基),现在有一个托管提供商作为12c及更高版本的odp.net包的一部分。此提供程序不需要任何非托管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的搜索顺序”

答案 4 :(得分:2)

修改IIS

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

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

答案 5 :(得分:1)

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

为了缩短它,它说:(如果页面仍然存在,只需转到页面并按照说明进行操作......) 1)从oracle站点下载并安装最新版本的odac 64位xcopy。 2)从oracle站点下载并安装最新版本的odac 32位xcopy。 怎么样?打开cmd shell作为ADMINSTARTOR并运行: C:\ 64bitODACLocation&GT; install.bat oledb c:\ odac \ odac64。 第一个参数是您要安装的组件。第二个参数是安装到的地方。 安装32版本也是这样的:c:\ 32bitODACLocation&gt; 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提供程序作为您的连接类型。将tnsnames.ora中条目的名称设置为&#34;服务器或文件名&#34;。用户名是架构名称(db name),password是架构的密码。你完成了!

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

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

干杯! GCR

答案 6 :(得分:1)

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

答案 7 :(得分:1)

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

应用以下解决方案

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

现在,它的工作原理是因为应用程序设置为32位和安装在Win2012 R2服务器上的oracle 32bit客户端,希望能为您工作。

答案 8 :(得分:0)

我在控制台应用程序中遇到此问题。 在我的情况下,我刚刚将平台目标更改为&#34;任何CPU&#34;当您右键单击解决方案并单击属性时,您可以看到,您将找到一个Tab&#34; Build&#34;点击它你会看到&#34;平台目标:&#34;将其更改为&#34;任何CPU&#34;,这将解决您的问题

答案 9 :(得分:0)

此解决方案适用于我,

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

答案 10 :(得分:0)

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

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

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

答案 11 :(得分:0)

我是控制台应用程序(它也应该适用于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),这可能会对您有所帮助。 我希望它会对你有所帮助。

答案 12 :(得分:0)

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

答案 13 :(得分:0)

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

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

我有完全相同的BadImageFormatException问题。编译为64位消除了异常,但它不是我的选项,因为我的应用程序使用32位activex组件,不能在64位工作。

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

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

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

答案 14 :(得分:0)

我也遇到了同样的错误,我检查了我的系统是否为64位,并且我正在使用oracle.DataAccess的32位版本,我添加了正确的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

答案 15 :(得分:0)

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

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

答案 16 :(得分:0)

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

有关使用

的信息,请参阅here

答案 17 :(得分:0)

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

image

答案 18 :(得分:-2)

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

答案 19 :(得分:-2)

对于ssis 2008,仅活动的32位运行,波纹管图像(单击此链接) Orcale ssis 2008

答案 20 :(得分:-3)

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