【问题标题】:How to make odp.net 12c to work with other oracle client如何使 odp.net 12c 与其他 oracle 客户端一起使用
【发布时间】:2015-04-22 16:53:14
【问题描述】:

我的机器上安装了 oracle 10g 客户端(完整版)和 11g 即时客户端。 我正在尝试使用 ODP.NET 12c。这就是我所做的。

  1. 将 Oracle.DataAccess.dll 添加到参考中。
  2. 将 OraOps12.dll 复制到我的可执行文件所在的文件夹中。

运行时出现“无法加载 DLL 'OraOps12.dll':找不到指定的模块。(来自 HRESULT 的异常:0x8007007E)”。

我认为这可能是由于依赖性问题。于是我又抄了12c的

  • oci.dll
  • oraociei12.dll
  • orannzsbb12.dll

然后我仍然遇到其他依赖错误。不过,我不想复制整个 InstantClient。

我的目标是让应用与其他版本的 Oracle 客户端一起工作。 我们的客户安装了不同版本的 Oracle 客户端。那么有什么方法可以让应用程序(ODAC12c)与客户当前版本的 Oracle 客户端一起工作,而无需安装 12c 客户端?

谢谢,

更新: 有几件事忘了说

  1. 我的 ODAC 是 32 位的,我在 x86 上编译了我的应用程序。

  2. 我没有使用 Oracle.ManagedDataAccess.dll,因为它不包含 BULKCOPY 类。如果有人知道包含批量复制类的 Oracle.ManagedDataAccess.dll 版本,请告诉我。

  3. 我们的客户已经为其他应用安装了不同版本的 Oracle 客户端,他们不想仅仅为了这个新应用而改变他们的环境。所以我的目标是让我的应用程序中的一个版本的 ODAC 与现有 Oracle 客户端的不同版本一起工作(每个客户环境都不同)。这可能吗?如果可以,怎么做?

【问题讨论】:

  • 为什么需要 12c?现有客户端是否不适用于您的应用?

标签: c# oracle dll odp.net


【解决方案1】:

你知道,我只花了 5 分钟寻找我记得之前尝试过的那个人……结果是你肖恩;)。

老实说,依赖客户端安装的东西是胡扯。我会使用完整的 xcopy 包,让它工作,然后向后工作,删除不需要的东西。

  • 不要运行它附带的 install.bat。这样做会添加有助于定位非托管二进制文件的注册表项,但您也有弄乱客户端安装副本的风险。
  • 将整个 xcopy 安装拖放到您应用的文件夹中作为子文件夹。
  • 相反,将 DllPath 设置为这个新的子文件夹

例子:

<oracle.dataaccess.client>
  <settings>
    <add name="DllPath" value="C:\app\user\product\11.1.0\client_1\BIN"/>
  • 然后设置Oracle_Home环境变量

例子:

Environment.SetEnvironmentVariable("ORACLE_HOME", @"C:\app\user\product\11.1.0\client_1\");

这篇文章做了类似的事情: http://dbaportal.eu/2013/02/22/true-xcopy-runtime-for-oracle-odp-net-application/

他甚至添加了一个重定向策略,以防他引用了引用特定版本的 Oracle.DataAccess.dll 的项目

不过,他使用批处理文件添加了他的 oracle 主页。我不太确定的部分是他还将他的新 xcopy 安装添加到具有相同批处理文件的路径中。 DllPath 应该解决这个问题,但如果我错了,你也可以在运行时这样做:

Environment.SetEnvironmentVariable("PATH", @"C:\app\user\product\11.1.0\client_1\BIN");

从这里开始,我将使用您正在使用的所有 ODP.net 功能设置一些基本单元测试,并获得一些积极的测试,然后向后工作 - 开始删除您不需要的内容,每次都运行您的测试。您也许可以使用 sysinternals procexp 来显示加载的 dll(或 procmon 来显示对文件的访问)。只需加载您的测试就足以锁定文件,这样您就可以删除所有未锁定的文件。

我不确定是否支持这样做。然后,Oracle 确实以非托管搜索顺序列出了“当前应用程序的目录”,因此他们也没有关门。

编辑: 找到这样做的其他人的链接之一: http://alderprogs.blogspot.com/2009/04/deploying-odpnet-with-oracle-instant.html

我不知道为什么,但他们单独下载了即时客户端(它已经是 xcopy 包的一部分)。

编辑 2016 年 4 月 15 日:如果您最近正在阅读本文,请注意两点。 1)如果您已经设置了 DllPath,我认为没有必要设置环境变量。 2) 当托管提供程序现在只需要一个或两个 dll 时,我认为这样做不值得。

【讨论】:

  • b_levitt,它按照您提供的 url 工作。谢谢!
  • “当托管提供程序现在只需要一个或两个 dll 时,我认为这样做不值得。”托管客户端非常出色……除非您从启用了 FIPS 模式的计算机连接到 11g 或更低的服务器。然后它就差很多了,因为它所做的只是爆炸。
  • @Andreas - 您需要阅读 shawn 针对他的标准发布的更新。如果您想保持系统不变,则不能只安装 odac。
【解决方案2】:

将单个 DLL 复制到不同的目录并希望它能正常工作是个坏主意。

一般来说,ODP.NET 提供程序只能与相应的 Oracle 客户端一起使用,即为了使用 ODP.NET 12,您还必须安装 Oracle 客户端 12。同样适用于版本 11 或 10。 唯一的例外是 ODP.NET 托管驱动程序,您只需要一个 DLL (Oracle.ManagedDataAccess.dll)。

此外,架构(32 位与 64 位)必须匹配。

如果您使用 OLEDB 提供程序,甚至不可能安装多个提供程序(对于每个架构) - 除非您一直通过操纵 PATH 变量和注册表来破解您的系统。

我的建议是:从您的计算机上删除所有 Oracle 客户端,然后正确安装 一个(或每个架构一个)Oracle 客户端。一个应用程序不太可能只与一个 Oracle 客户端版本一起工作。在一台机器上同时安装 32 位和 64 位也是一个好方法,请按照以下说明进行操作:Install Oracle x86 and X64 on one machine

如果您确实需要使用不同的 Oracle 客户端版本来测试您的应用程序,请设置几台测试 PC(可能在 Virtual-Box 中),每台都使用不同的客户端版本。否则处理起来会很困难。

更新:

我认为每个(非托管)ODP.NET 版本仅适用于相应版本的 Oracle 客户端。也许偶然有一些组合可以解决,但通常版本应该匹配。

我看到了两种不同的解决方案:

(1) 要求您的客户安装包括 ODP.NET 在内的 Oracle 客户端。他可以选择版本,只有架构(32 位或 64 位)必须匹配。那么您的应用程序不会提供任何 ODP.NET。

在您的*.csproj,分别。 *.vbproj 文件定义你的参考是这样的:

    <Reference Include="Oracle.DataAccess">
      <SpecificVersion>False</SpecificVersion>
      <Private>False</Private>
    </Reference>

Version=...processorArchitecture=... 等属性不是必需的。那么您的应用程序应该可以在任何 Oracle/ODP.NET 版本上运行。

您的客户可以从这里下载 ODP.NET 提供程序:Oracle Data Access Components (ODAC) for Windows Downloads 并将其安装在现有的 Oracle 客户端安装之上。在readme.txt 它说“这个 zip 文件的文件不能安装在现有的 基于 Oracle Universal Installer (OUI) 的 Oracle Home 安装。”,但是我看不出有什么不这样做的理由。它运行良好,您只需为现有 Oracle 安装仔细提供正确的文件夹并更正 ORACLE_HOME 名称并执行不安装依赖项。

(2) 在您的安装脚本/exe 中确定客户安装的 Oracle 客户端的版本并根据 ODP.NET 复制到客户机器。

为了确定Oracle客户端的版本,您可以在PATH环境提供的文件夹中搜索文件oci.dlloci.dll 是一个普通的 .NET 程序集,因此您可以轻松读出版本。

要正确安装 ODP.NET,请遵循文件 configure.bat,它是下载的 ODP.NET XCopy 版本的一部分。在我看来,这个批处理文件很容易理解。 基本上是这样

1 - 将文件 Oracle.DataAccess.dll 复制到目标机器

2 - 将不同的资源文件*\Oracle.DataAccess.resources.dll 复制到目标机器

3 - 将这些 DLL 添加到 GAC。这可以通过gacutil.exeOraProvCfg.exe(包含在下载器 ZIP 文件中)来完成,或者您的设置应用程序提供此操作。

4 - 制作一些注册表条目。较新的 ODP.NET 版本写入/读取到 HKLM\SOFTWARE\Wow6432Node\Oracle\ODP.NET(对于 32 位),分别。 HKLM\SOFTWARE\Oracle\ODP.NET(对于 64 位)。较旧的 ODP.NET 版本使用 HKLM\SOFTWARE\Oracle\KEY_{ORACLE_HOME_KEY}\ODP.NET\(64 位)和 HKLM\SOFTWARE\Wow6432Node\Oracle\KEY_{ORACLE_HOME_KEY}\ODP.NET\(32 位)代替

就是这样,您应该可以将其包含在您的设置中。

【讨论】:

  • 嗨 Wernfried,感谢您的回复。我明白如果我按照你的建议去做,它会起作用。我更新了我的问题,以使我的应用程序中的一个版本的 ODAC 与现有 Oracle 客户端的不同版本一起工作(每个客户环境都不同)。这可能吗?如果可以,怎么做?
  • 您的意思是在您的应用程序中提供Oracle.DataAccess.dll 的副本?
猜你喜欢
  • 2014-09-22
  • 2012-01-01
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
相关资源
最近更新 更多