提供者与Oracle客户端版本不兼容
Posted
技术标签:
【中文标题】提供者与Oracle客户端版本不兼容【英文标题】:The provider is not compatible with the version of Oracle client 【发布时间】:2010-10-14 03:30:47 【问题描述】:我正在尝试在我的 ASP.net 项目中使用 Oracle ODP.NET 11g (11.1.0.6.20) Instant Client 作为 数据提供者,但是当我运行 aspx 页面时收到“提供程序与 Oracle 客户端的版本不兼容”错误消息。任何帮助将不胜感激。
我在 Visual Studio 2005 中引用了 Data Provider,后面的代码如下所示:
using Oracle.DataAccess.Client;
..
OracleConnection oOracleConn = new OracleConnection();
oOracleConn.ConnectionString =
"Data Source=MyOracleServerName;" +
"Integrated Security=SSPI";
oOracleConn.Open();
//Do Something
oOracleConn.Close();
页面的错误如下所示:
Exception Details: Oracle.DataAccess.Client.OracleException: The provider is not compatible with the version of Oracle client
Source Error:
Line 21:
Line 22:
Line 23: OracleConnection oOracleConn = new OracleConnection();
Line 24: oOracleConn.ConnectionString =
Line 25: "Data Source=MyOracleServerName;" +
[OracleException (0x80004005): The provider is not compatible with the version of Oracle client]
Oracle.DataAccess.Client.OracleInit.Initialize() +494
Oracle.DataAccess.Client.OracleConnection..cctor() +483
Stack Trace:
[TypeInitializationException: The type initializer for 'Oracle.DataAccess.Client.OracleConnection' threw an exception.]
Oracle.DataAccess.Client.OracleConnection..ctor() +0
Boeing.IVX.Web.RoyTesting.Page_Load(Object sender, EventArgs e) in C:\Documents and Settings\CE218C\Desktop\IVX.Net\Web\IVX\RoyTesting.aspx.cs:23
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +33
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436
【问题讨论】:
【参考方案1】:IIS/IWAM 用户是否拥有 Oracle 目录的权限?您可以使用其他应用程序(例如 Excel 或 Access)连接到此数据源吗?
【讨论】:
【参考方案2】:在我看来,尽管您使用 Oracle 即时客户端的 ODP,但 ODP 可能会尝试使用实际的 Oracle 客户端。你的机器上是否也安装了标准的 Oracle 客户端?我记得 Oracle 对同一台机器上的多个客户端非常挑剔。
【讨论】:
【参考方案3】:我只安装了 Oracle Data Provider for .NET 2.0 (11.1.0.6.20),我没有安装 Oracle Instant Client (11.1.0.6.0)。
我刚安装,错误消失了!
【讨论】:
您可以简单地将 4 个即时客户端 DLL 复制到与您的 EXE 相同的文件夹中,而不是安装客户端吗? (这些文件:oci.dll orannzsbb11.dll oraocci11.dll oraociicus11.dll) @Chris:是的,你可以。不过,根据我的经验,您需要 oci.dll、orannzsbb11.dll、oraociicus11.dll、oraops11w.dll 和 oracle.dataaccess.dll 对我来说其他方式 - 我安装了客户端,但没有安装提供程序【参考方案4】:这可能是由针对 32 位 Oracle 客户端运行 64 位 .NET 运行时引起的。如果您的服务器在 64 位上运行应用程序,则可能会发生这种情况。它将使用 64 位运行时运行 .NET 应用程序。您可以在 VS 中设置项目的 CPU 标志以在 32 位运行时中运行。
【讨论】:
刚碰到这个。在(32 位)测试应用程序中工作,然后在 IIS 中失败。我没有要求所有涉及的程序集都是 32 位的,而是改为 32 位的 AppPool。【参考方案5】:我遇到了完全相同的问题。编译应用程序后,我删除了(忘记了我已经删除了)oraociei11.dll。它在尝试执行时给出了这个错误。所以当它找不到 oraociei11.dll 的 dll 时,它会显示这个错误。可能还有其他情况会出现此错误,但这似乎是其中之一。
【讨论】:
【参考方案6】:我一直在进一步研究这个问题,你只需要从同一个下载版本的 ODP.Net 中获取所有适当的 DLL,并将它们放在与你的 Exe 文件相同的文件夹中,因为 ODP.Net 很挑剔关于不混合版本号。
我已经在这里解释了如何做到这一点:http://splinter.com.au/using-the-new-odpnet-to-access-oracle-from-c 不过,这里是它的要点:
下载ODP.Net 解压文件 解压其中的所有 JAR 获取这些刚刚解压的 dll: oci.dll(从“oci.dll.dbl”重命名) Oracle.DataAccess.dll oraociicus11.dll OraOps11w.dll orannzsbb11.dll oraocci11.dll ociw32.dll(从“ociw32.dll.dbl”重命名) 将所有 DLL 与 C# 可执行文件放在同一文件夹中【讨论】:
您的解决方案对我有用——在我发现之前找到了您的博客文章。你是男人。谢谢! :-) 另外,使用最新版本的 ODAC,我不需要解压缩任何 JAR....dll 文件位于我的 oracle home 的各个目录中。一个简单的 windows 搜索很快就找到了它们。 另外,我在我的开发机器上使用了最新版本的 ODAC (11.2.0.1.2),我需要的唯一文件是:oci.dll、Oracle.DataAccess.dll、oraociei11。 dll,OraOps11w.dll。正如克里斯指出的那样,确保它们与您的可执行文件位于同一文件夹中。 ;-) 听起来新版本更容易找到dll。伟大的!现在,oracle 将它们滚动到一个简单的 dll 中需要多长时间... 如果可以的话,这些天你可能应该使用 C# 托管驱动程序 :) 如果您的客户安装了(正常)Oracle 客户端,此解决方案可能会失败,因为Oracle.DataAccess.dll
安装在GAC 中。在这种情况下,Oracle.DataAccess.dll
取自 GAC(优先于您的 .exe 文件夹),但其他 DLL 取自您的 .exe 文件夹。这可能会导致“版本不兼容”错误。【参考方案7】:
在目标机器上安装 ODP.Net 应该可以解决问题...复制 dll 看起来不是一个好主意...
【讨论】:
【参考方案8】:对于 Oracle 11g (11.1.0.7.20),我必须添加以下 dll 以及我的 Exe 才能工作。
-
oci.dll
OraOps11w.dll
oraociicus11.dll(非常大,接近 30mb)
Oracle.DataAccess.dll
【讨论】:
你想说 130 MB【参考方案9】:同时寻找 IIS 应用程序池 Enable 32-bit true or false flag,当你看到这个消息时,一些 oracle 论坛指导我这样做!
【讨论】:
【参考方案10】:我们遇到了同样的问题,因为我们的 DBA 更新了网络共享上的 Oracle.Data.dll 程序集。从项目中删除引用,然后重新添加即可解决问题。
【讨论】:
【参考方案11】:我有同样的问题,但在我的情况下,我不能只将 dll 复制到 bin 文件夹中,然后我只能“重新绑定”程序集版本。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89B483F429C47342" culture="neutral"/>
<bindingRedirect oldVersion="2.112.2.0" newVersion="2.112.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
【讨论】:
【参考方案12】: 在 64 位计算机上,将“msvcr71.dll”从 C:\Windows\SysWOW64 复制到 应用程序的 bin 目录。 在 32 位计算机上,将“msvcr71.dll”从 C:\Windows\System32 复制到 应用程序的 bin 目录。http://randomdevtips.blogspot.com/2012/06/provider-is-not-compatible-with-version.html
【讨论】:
【参考方案13】:只需两步即可解决此问题。
-
转到应用程序池的高级设置并将“启用 32 位应用程序”标志设置为 True。
现在确保 Bin 中的所有 Dll 都是 32 位版本...
祝你好运。
【讨论】:
@mazhar-abbas,你能请。指出我可以在其中设置“启用 32 位应用程序?是在 IIS 还是 Project 中?【参考方案14】:最近我不得不处理一个较旧的项目,其中解决方案和所有包含的项目都针对 x32 平台。我继续尝试在所有地方复制 Oracle.DataAccess.dll 和所有其他建议的 Oracle 文件,但每次都碰壁。最后,头上的灯泡亮了(8 小时后 :)),并要求检查已安装的 ODAC 组件及其平台。我已经安装了所有 64 位 (x64) ODAC 客户端,但没有安装 32 位 (x32)。安装了32位的ODAC,问题就消失了。
如何检查已安装 ODAC 的版本:查看文件夹 C:\Windows\assembly。 “处理器架构”属性将通知平台安装的 ODAC。
8 小时对于灯泡点亮来说是一段很长的时间。难怪我总是要在工作中吃力:)。
【讨论】:
注意,C:\Windows\assemblies
仅显示 .NET 框架版本 2.0 之前的程序集。 3.x/4.x版本不显示,见***.com/questions/28213105/…【参考方案15】:
为了解决这个持续了 3 个小时的问题,我采取了以下措施:
在位于 C:\oracle\product\11.2.0
的 Oracle 主目录下,我有一个名为 client_1
的文件夹,我之前在其中安装了用于 Windows 64 位的 ODP.NET
位。
后来在尝试使用 Visual Studio 2012 调试我的 ASP.NET Web API 应用程序时,我不断收到以下错误消息:提供程序与 Oracle 客户端的版本不兼容.
搜索 Google 我发现发生这种情况是因为我使用的是 ODP.NET
64 位。然后我为 Windows 32 位抓取了 ODP.NET
并安装了它,但我一直收到相同的错误消息。
解决方案: 删除文件夹 client_1
并重新安装 ODP.NET
32 位。安装程序在某种程度上混合了 64 位版本和 32 位版本的位。去图...
现在我又高兴了,我可以打开一个新的OracleConnection
。最后! :)
【讨论】:
【参考方案16】:经过几个小时的故障排除后,我发现这个问题是由于我的项目 bin 目录中有 Oracle.DataAccess.dll (v4.0) 引起的,但运行时还加载了 Oracle.DataAccess.dll (v2.x) GAC。删除并读取项目引用中的 Oracle.DataAccess 条目为我解决了这个问题。
在我的情况下,这里提到的其他文件似乎不是必需的。
更新
“提供程序与 Oracle 客户端的版本不兼容”错误的根本原因(通常)是托管程序集试图加载与版本不匹配的非托管库。看来您可以通过在 web.config1 中指定库路径来强制 Oracle 驱动程序使用正确的库
<configuration>
<oracle.dataaccess.client>
<settings>
<add name="DllPath" value="C:\oracle\bin"/>
<!-- ... -->
</settings>
</oracle.dataaccess.client>
</configuration>
【讨论】:
谢谢!您的解决方案让我知道 2 天后工作(我有 Visual Studio 2010 Net 4,Oracle 10g 客户端)...我看到 GAC,当然我已经安装了 3 个版本的 Oracle.DataAccess.dll,我卸载了所有(和删除“DbProviderFactories”中无效的 machine.config 键),并仅重新安装 ODAC1120320 x64。它有效。【参考方案17】:对于初学者,您应该“忽略”这里所有关于 x86/x64 的讨论,而是尝试使用 ODP.NET 托管驱动程序(如果您使用的是 .Net v4+):
https://www.nuget.org/packages/Oracle.ManagedDataAccess/
https://www.nuget.org/packages/Oracle.ManagedDataAccess.EntityFramework/
Oracle ODP.net Managed vs Unmanaged Driver
避免所有“非托管”什么DLL什么架构问题! :D(大约是 Oracle 的时间)。
NuGet 包(也适用于 11g):
旧的/手动方法:
有关如何转换为使用 托管 库的信息:
首先,这是 managed 与 unmanaged 的代码对比:http://docs.oracle.com/cd/E51173_01/win.122/e17732/intro005.htm#ODPNT148 确保您已下载 ODP.NET,仅限托管驱动程序 Xcopy 版本 从下载的 zip 文件中,复制并粘贴到您的项目目录中: Oracle.ManagedDataAccessDTC.dll Oracle.ManagedDataAccess.dll 添加对 Oracle.ManagedDataAccess.dll 的引用 确保您的 exe 与两个 dll 一起发布(添加到 VS2010 中的应用程序文件夹)【讨论】:
好消息是,Oracle 终于有了一个完全托管的驱动程序。拖着那个 100mb 的 dll 是一个真正的负担。 托管驱动程序对我来说非常有用 - 自从使用它后我没有遇到任何问题/您可以将您的项目设置回 AnyCPU 等,它非常有效:) 每个人都知道,虽然托管提供程序很好,但它缺少完整提供程序允许的许多功能。也就是说,Oracle 的内置加密。 Oracle 的文档至少可以说是“分散”的。这是一些unsupported methods 的一个很好的链接。此外,驱动程序本身带有一个readme
,其中概述了一些限制。
使用托管驱动程序是最终的解决方案!每次我都想在类型不匹配时花费所有时间时,我都有一个噩梦【参考方案18】:
Chris 的解决方案也对我有用。但是,我确实收到了一条以下错误消息:
Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format.
显然,在 Oraclish 的外语中,这意味着您的程序要么针对所有平台,要么针对 32 位机器。 只需将 Project Properties 中的目标平台更改为 64 位并希望获得最好的结果。
【讨论】:
这实际上是 .NETish,而不是 Oraclish【参考方案19】:对于仍然遇到此问题的任何人:基于这篇文章
http://oradim.blogspot.com/2009/09/odpnet-provider-is-not-compatible-with.html
我发现我的服务器缺少 Microsoft C++ Visual Runtime Library - 因为安装了 Visual Studio,所以我在我的开发机器上拥有它。我从这里下载并安装了(当前)最新版本的库:
http://www.microsoft.com/en-us/download/details.aspx?id=13523
运行设置,C# 中的 oracle 调用成功了!
【讨论】:
老兄....甲骨文....我们可以讨论一下吗?过来,在角落里。听着,我花了一整天的时间弄清楚“提供程序不兼容”到底是什么意思,后来才发现这是因为没有满足某些安装依赖项。请--不--我要求让您的安装程序在安装时检查这些依赖项,如果不是,警告用户遇见了。谢谢。 顺便说一句,我不得不多次回到这个 *** 问题,每次都有不同的答案适用于我。这造成了多么浪费时间和金钱。【参考方案20】:让我们做一些总结:
错误消息“提供程序与Oracle客户端版本不兼容”可能由多种原因引起。
您没有安装 Oracle 客户端。在这种情况下,错误消息确实具有误导性。
Oracle Instant Client 中不包含用于 .NET 的 Oracle 数据提供程序(ODP.NET,即文件 Oracle.DataAccess.dll
),它必须单独安装(从 32-bit Oracle Data Access Components (ODAC) 或 64-bit Oracle Data Access Components (ODAC) Downloads 下载)或者您必须选择根据 Oracle Universal Installer (OUI) 中的选项。
注意,当安装 Oracle Data Provider >= 12.1 时,提供程序不会自动注册到 GAC。如果需要,您必须手动注册,请参阅 Oracle Doc 2272241.1。
ODP.NET 的版本与安装的 Oracle 客户端版本不匹配。您甚至必须检查次要版本号!例如,Oracle.DataAccess.dll
版本 4.112.3.0 与 Oracle 客户端 11.2.0.4 不兼容。仔细检查 ODP.NET 和 Oracle 客户端的版本。您可以在oraociei*.dll
和/或OraOps*w.dll
上使用sigcheck 来获取Oracle 客户端的版本。
注意不同的编号方案。文件版本 4.112.3.0 表示:.NET Framework 版本 4,Oracle 版本 11.2.0.3.x。
ODP.NET 版本有“1.x”、“2.x”和“4.x”。这些数字与 Microsoft .NET Framework 版本 1.0.3705/1.1.4322、2.0.50727 和 4.0.30319 相关。在 Oracle Client 11.1 之前版本“1.x”可用。 Oracle Client 11.2 引入了版本“4.x”
ODP.NET 的架构(32 位或 64 位)与您的应用程序架构不匹配。 32 位应用程序仅适用于 32 位 Oracle Client/ODP.NET,而 64 位应用程序则需要 64 位 Oracle Client/ODP.NET。 (除非您使用 ODP.NET 托管驱动程序)
.NET Framework 版本不匹配。例如,如果您使用 Target .NET Framework 2.0 编译应用程序,则不能使用 ODP.NET 4.x 版。 .NET Framework 目标版本必须等于或高于 ODP.NET 的版本。
你的开发机器上Oracle.DataAccess.dll
的版本(即编译时加载的版本)高于目标机器上的版本。
请注意,Oracle.DataAccess.dll
可能从 GAC 加载,默认情况下优先于任何本地提供的文件。
解决方案
考虑使用ODP.NET Managed Driver,可以从Oracle 页面下载:64-bit Oracle Data Access Components (ODAC) Downloads。
在那里,您只需将Oracle.ManagedDataAccess.dll
文件复制到您的应用程序目录,不需要其他任何东西。它适用于 32 位和 64 位。
在您的*.csproj
,分别。 *.vbproj
编辑您对 ODP.NET 的引用,如下所示:
<Reference Include="Oracle.DataAccess">
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
Version=...
或 processorArchitecture=...
等属性不是必需的。 您的应用程序将根据所选架构和目标 .NET 框架加载正确的 -> 未 100% 验证Oracle.DataAccess.dll
(前提是它已正确安装)
如果您不知道目标机器上的 Oracle 客户端版本(例如,它可能是您客户的机器):转到上面提到的下载页面并至少下载 XCopy Oracle 数据访问组件的版本。解压缩 zip 并将 Oracle.DataAccess.dll
文件复制到本地计算机。在你的 VS 项目中引用这个(很可能是过时的)DLL。此 DLL 的版本是您的应用程序可以使用的最低版本的 ODP.NET。当您运行您的应用程序时,GAC 中的发布者策略将重定向到实际安装的版本。
我认为获取单个 DLL 并将它们复制到特定文件夹不是一种明智的方法。它可能在“裸机”机器上工作,但如果您的目标机器安装了任何 Oracle 产品,则版本不匹配的风险很高。从您的机器上卸载所有 Oracle 产品并进行全新安装。看一下How to uninstall / completely remove Oracle 11g (client)? 以获得真正干净的机器。
如果您必须同时使用 32 位和 64 位应用程序,请按照以下说明在一台机器上安装这两个版本:
假设:Oracle Home 名为OraClient11g_home1
,客户端版本为 11gR2。
可选择删除任何已安装的 Oracle 客户端
下载并安装 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_x86
和C:\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 库而无需对您的系统进行任何进一步修改。
创建符号链接的命令:
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
。
如果您想在之后手动安装 ODP.NET,请注意选择合适的文件夹进行安装。
尽管名称文件夹 C:\Windows\System32
包含 x64 库,而 C:\Windows\SysWOW64
包含 x86(32 位)库。不要混淆。
也许将TNS_ADMIN
环境变量(分别在注册表中的TNS_ADMIN
条目)设置为一个公共位置是一个明智的选择,例如TNS_ADMIN=C:\Oracle\Common\network
。
【讨论】:
这个 IMO 比实际答案有更多的知识要带走。因此,如果我有一个用于 .net 4 的 x86 应用程序并且数据库版本在 9i 中,那么如果用户有 32 位或 64 位 Windows,他们需要什么客户端版本? Oracle 表示任何客户端版本都与任何数据库版本兼容。答案是 32 位用户安装 32 位版本,64 位用户安装 64 位版本并使用 ODP.NET 托管驱动程序来决定它正在与哪个操作系统对话? 当您使用 ODP.NET 托管驱动程序时,不需要安装任何 Oracle 客户端 - 这是它的主要优势。它适用于 x86 和 x64 应用程序。如果没有“ODP.NET 托管驱动程序”,x86 应用程序还需要 x86(即 32 位)Oracle 客户端,无论数据库服务器架构是什么。 我刚刚遇到“需要安装 Microsoft Visual C++ 2010 Redistributable”——您应该将其添加到您的摘要中。 我认为这个错误与Oracle或ODP.NET无关或引起 它对我有用,我从nuget包Oracle.DataAccess.x86
安装Oracle.DataAccess.dll
,它的Dll版本是2.112.1.0
,所以我匹配安装Oracle客户端版本Oracle Database 11g Release 2 Client (11.2.0.1.0) for Microsoft Windows (x64)
HERE然后问题解决了!【参考方案21】:
我没有走上获取新 DLL 的道路。我们有一堆现有的项目运行良好,只有我的新项目让我头疼,所以我决定尝试其他的。
我的项目使用的是内部开发的 Internal.dll,它依赖于 Oracle.DataAccess.dll v4.112.3.0
。出于某种原因,在发布时,Visual Studio 总是上传v4.121.0.0
,即使它没有在任何配置文件中明确指定。这就是我收到错误消息的原因。
所以我做的是:
-
将 Internal.dll 从成功运行的项目之一复制到我网站的
/bin
(只是为了安全起见)。
将 Oracle.DataAccess.dll 从成功运行的项目之一复制到我的网站的/bin
。
从我的网站添加对它们的引用。
最后 Oracle.DataAccess 引用出现在 myWebSite.csproj
中,但它显示了错误的版本:v4.121.0.0
而不是 v4.112.3.0
。
我手动更改了myWebSite.csproj
中的引用,所以现在改为:
<Reference Include="Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Oracle.DataAccess.dll</HintPath>
</Reference>
【讨论】:
在 bin 文件夹中添加对 dll 的引用是一个真的坏主意。bin
和 obj
文件夹是 output 文件夹;这是构建项目时 dll 所在的位置。您应该能够随时删除这些文件夹而不会产生冲突。通常这些文件夹在源代码管理中被忽略。标准做法是创建一个 External References
文件夹,您可以在其中放置引用的 dll。
@notfed 看来你是对的。我会记住这一点。
顾名思义,它只是编译器的 hint 路径,而不是强制引用。首先在 GAC 中搜索 Oracle.DataAccess.dll。即使您完全删除HintPath
,它也应该可以工作。【参考方案22】:
我在使用 Oracle.DataAccess.dll v4.121.2.0 时遇到了同样的问题。带有 2 个家庭安装(32 位和 64 位版本)。 32 位版本工作,64 位版本没有。
就我而言(经过 2 天的尝试),我发现问题出在 64 位家庭版本的权限上。该版本中的许多目录具有独占权限,其中“Authenticated Users”角色没有“读取”权限,默认情况下在父目录上设置。这些子目录包括“bin”、“network/admin”、“nls”、“oracore”、“RDBMS”和可能的其他目录。我通过从 sysinternals 过滤掉“进程监视器”(Procmon.exe)实用程序中的“访问被拒绝”结果找到了它们。一旦权限从父目录继承到这些子子目录,一切就开始工作了。
我没有覆盖整个oracle home的权限,所以我一次只做一个目录,但我想如果你不太担心安全性,你可以在整个相应的oracle home上重置它目录。
【讨论】:
【参考方案23】:我在安装 Oracle Data Tools for Visual Studio 2015 后遇到了这个问题,然后与 Oracle 打了一个小时。我决定再次尝试重新安装 Oracle 客户端,而不是像文件复制、配置更改等那样弄得一团糟,这对我有用。
【讨论】:
【参考方案24】:TLDR 版本:
请改用 12c 100% managed provider。 如果必须使用旧提供程序,则需要将 Oracle.DataAccess.dll 指向正确版本的非托管 Oracle 客户端 Dll。如果您的机器上安装了多个 Oracle 客户端,这可能很简单,例如在您的应用配置中包含“DllPath”配置变量(见下文),但您可能还需要安装一个新的 Oracle 客户端来指向。完整版:
首先,让我们确保我们了解旧的非托管提供程序(不是新的 12c 100% 托管提供程序)的组件。它由两部分组成:
-
托管的 .net 组件 - Oracle.DataAccess.dll
非托管(非 .net)客户端
简单地说,Oracle.DataAccess.dll 几乎只是一个包装器,将 .net 指令转换为非托管客户端的 ORACLE-NET 指令。
也就是说,当您加载 Oracle.DataAccess 时,它会尝试查找所需的非托管客户端 dll 的顺序。来自Oracle Documentation:
Oracle.DataAccess.dll 搜索依赖的非托管 DLL(例如 作为 Oracle 客户端)基于以下顺序:
1.应用程序或可执行文件的目录。
2.DllPath 设置由应用程序配置或 web.config 指定。
3.machine.config指定的DllPath设置。
4.Windows注册表指定的DllPath设置。
HKEY_LOCAL_MACHINE\Software\Oracle\ODP.NET\version\DllPath
5.Windows PATH 环境变量指定的目录。
因此,在您的情况下,您的应用遵循上述过程,发现一个路径包含相对于您正在使用的 Oracle.DataAccess.dll 程序集太旧的未管理 dll。
可能只是那台机器上安装的唯一 Oracle 客户端太旧了。但是,如果您在机器上安装了多个客户端,并且首先在不同但较旧的安装中找到了未管理的文件,那么这就会发挥作用。如果是后者,简单的做法是在您的配置中使用 dllPath 配置变量并将其指向正确的 Oracle Home Bin 文件夹:
<configuration>
<oracle.dataaccess.client>
<add key="DllPath" value="c:\oracle\product\1.1.0-xcopy-dep\BIN"/>
</oracle.dataaccess.client>
</configuration>
如果您想安装客户端的新副本,xcopy version 是最小的并包含“即时客户端”并将上面的 DllPath 指向这个新位置。但是任何 oracle 客户端安装都可以工作。
但是,如果您想避免所有这些非托管客户端解析问题,请查看您是否可以更新您的应用程序以使用 100% 托管提供程序 - 它确实只是一两个托管程序集,而不依赖于非托管文件。
如果它安装在您的 bin 目录和 GAC 中,您也可能没有加载您认为的 Oracle.DataAccess.dll,但我认为这是不太可能的情况。请参阅assembly resolution process 了解更多信息。
【讨论】:
【参考方案25】:这里有很多理论答案,但这里有一个工作示例,您可以复制粘贴并立即进行测试:
-
我安装了 Oracle Express 数据库 OracleXE112,它已经附带了一些预安装的演示表。
启动安装程序时,系统会要求您输入密码。我输入“xxx”作为密码。 (不用于生产)
我的服务器运行在机器192.168.1.158上
在服务器上,您必须明确允许访问 Windows 防火墙 中的进程 TNSLSNR.exe。此进程侦听端口 1521。如果您从以下代码中收到超时错误,请检查您的防火墙。
选项 A: 对于 C#(.NET2 或 .NET4),您可以下载 ODAC11,您必须从中将 Oracle.DataAccess.dll 添加到您的项目中。此外,此 DLL 依赖于:OraOps11w.dll、oci.dll、oraociei11.dll (130MB!)、msvcr80.dll。
这些 DLL 必须与 EXE 位于同一目录中,或者您必须在以下位置指定 DLL 路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.112.4.0\DllPath
。在 64 位机器上另外写入 HKLM\SOFTWARE\Wow6432Node\Oracle\...
选项 B:如果您已下载 ODAC12,您需要 Oracle.DataAccess.dll、OraOps12w.dll、oci.dll、oraociei12.dll(160MB!)、oraons.dll、 msvcr100.dll。注册表路径是HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\4.121.2.0\DllPath
选项 C: 如果您不想要超过 100 MB 的大型 DLL,您应该下载 ODP.NET_Managed12.xxxxxxxx.zip,您可以在其中找到 Oracle.ManagedDataAccess.dll
,它只有 4 MB,是一个纯托管 DLL,它也适用于 32 位和 64 位进程,不依赖于其他 DLL,也不需要任何注册表项。
以下 C# 代码适用于我在服务器端无需任何配置(只是默认安装):
【讨论】:
当您只需要一个正在运行的客户端时,安装整个 Oracle 数据库服务器相当过分。 反正你的回答很差。无需将任何 Oracle dll 复制到应用程序目录,因为默认安装时您通过 ‰PATH% 找到它们(除非您自己修改) Registy 提示仅适用于.version 4.x 并且仅适用于32 位 Oracle 客户端。但是 32 位与 64 位不匹配是这个问题的主题。 您的评论表明您没有阅读我的答案。如果我想编写一个与 Oracle 服务器通信的应用程序,则无需从 Oracle 安装任何东西。我只是使用上面提到的 DLL 并将它与我的应用程序一起分发。所以最终用户机器上的 PATH 变量中不会有任何内容。顺便说一句,使用 PATH 变量(来自 1980 年的旧 DOS 时代)在现代软件中被高度弃用。我的回答推荐 OPTION C,它不需要任何注册表路径并且不依赖于 32 位或 64 位。我提到选项 A 和 B 只是为了完整。 我认为如果没有正确的 %PATH% 设置,您的 Windows 将根本无法工作 - 即使在版本 10 中也是如此。我在回答中提到,使用您的应用程序手动复制任何 Oracle dll 是不明智的。我不知道这些 dll 的源代码,但您的客户端可能存在更多您看不到的依赖项,例如由语言设置、字符集、时区等触发。当我使用Oracle.DataAccess.dll
进行跟踪时,程序总共加载了 35 个 Oracle DLL!最好正常安装 Oracle 客户端 - 当然,除非您使用 ODP.NET 托管驱动程序。
我想我提到了我的担忧:(1)安装数据库是无用的,即矫枉过正。 (2) 选项 A 和 B 仅在某些条件下有效,例如它不从注册表中读取任何 NLS 设置(您需要文件oracle.key
)。为了兼容性,您还必须考虑次要版本。例如,Oracle.DataAccess, Version=2.112.2.0
不适用于 OraOps11w.dll
版本 2.112.4.0。【参考方案26】:
我遇到了类似的问题,根本原因是 GAC 有 2 个 oracle.dataaccess 版本,即 v4.0_4.112.2.0 和 v4.0_4.112.4.0 。我的应用程序引用的是 v4.0_4.112.2.0 ,所以当我从 GAC 中删除 v4.0_4.112.4.0 时,它工作正常。
GAC 路径:C:\Windows\Microsoft.NET\assembly\GAC_64\Oracle.DataAccess
之前:
之后:
要删除一个版本,只需从 GAC 中删除相应的文件夹即可。
【讨论】:
【参考方案27】:如果您有多个 oracle 客户端,或者有时如果您引用不同的版本,则在使用非托管 oracle 引用时可能会发生此问题 有两种方法可以解决:
第一个快速的解决方案是删除非托管引用并使用 NuGet 中的托管引用查看此之前使用此选项Differences between the ODP.NET Managed Driver and Unmanaged Driver
第二种解决方案是修复项目非托管目标版本,如下所示:
然后检查oracle GAC版本
从运行 (Win+R) "%windir%\Microsoft.NET\assembly"
进入 gac检查与您项目平台匹配的平台
检查您的目标平台(右键单击您的项目>属性)
从 gac 文件夹搜索到 Oracle.DataAccess
右键单击Oracle.DataAccess > 属性> 详细信息并检查版本
如果您发现版本不同,这是一个问题,要修复它,我们需要重定向程序集版本(在启动项目中转到配置文件并添加以下部分)
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="4.121.2.0" />
</dependentAssembly>
</assemblyBinding>
像这样
oldVersion : 应该涵盖您的项目版本 newVersion : GAC 版本 publicKeyToken:来自 GAC
【讨论】:
以上是关于提供者与Oracle客户端版本不兼容的主要内容,如果未能解决你的问题,请参考以下文章
为啥navicat连接oracle数据库以及新建查询时会闪退