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_x86
和C:\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_HOME
为C:\Windows\System32\ora112
-
将registry值
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
环境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
- select应用程序池。
- 在ASP .NET V4.0 Classic中使用Clic。
- select高级设置。
- 通常情况下,选项启用32位应用程序,默认为false。 selectTRUE。
- 刷新并检查网站。
评论:
平台: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中。