如何使 odp.net 12c 与其他 oracle 客户端一起工作
How to make odp.net 12c to work with other oracle client
我的机器上安装了 oracle 10g 客户端(完整版)和 11g 即时客户端。
我正在尝试使用 ODP.NET 12c。这是我所做的。
- 已将 Oracle.DataAccess.dll 添加到参考文献。
- 复制OraOps12.dll到我的可执行文件所在的文件夹。
当运行我得到了"Unable to load DLL 'OraOps12.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"。
我认为这可能是由于依赖性问题。所以我进一步复制了12c的
- oci.dll
- oraociei12.dll
- orannzsbb12.dll
然后我仍然遇到其他依赖性错误。不过,我不想复制整个 InstantClient。
我的目标是让应用程序与其他版本的 Oracle 客户端一起使用。
我们的客户安装了不同版本的 Oracle 客户端。那么有什么方法可以让应用程序 (ODAC12c) 与客户当前版本的 Oracle 客户端一起工作而无需安装 12c 客户端?
谢谢,
更新:
忘了说几件事
我的 ODAC 是 32 位的,我在 x86 上编译了我的应用程序。
我没有使用 Oracle.ManagedDataAccess.dll 因为它不包含 BULKCOPY classs。如果有人知道包含 bulkcopy class 的 Oracle.ManagedDataAccess.dll 版本,请告诉我。
我们的客户已经为其他应用程序安装了不同版本的 Oracle 客户端,他们不想仅仅为了这个新应用程序而改变他们的环境。所以我的目标是让我的应用程序中的一个版本的 ODAC 与不同版本的现有 Oracle 客户端一起工作(每个客户环境都不同)。这可能吗?如果可能,怎么办?
将单个 DLL 复制到不同的目录并希望它能工作是个坏主意。
通常 ODP.NET 提供程序只能与相应的 Oracle Client 一起工作,即为了使用 ODP.NET 12,您还必须安装 Oracle Client 12。同样适用于版本 11 或 10。
唯一的例外是 ODP.NET Managed Driver,在那里你只需要一个 DLL (Oracle.ManagedDataAccess.dll).
此外,体系结构(32 位与 64 位)必须匹配。
如果您使用 OLEDB 提供程序,则甚至不可能安装多个提供程序(针对每个体系结构)- 除非您一直通过操纵 PATH
变量和注册表来破解您的系统。
我的建议是:从您的计算机中删除所有 Oracle 客户端,并仅正确安装 一个(或每个体系结构一个)Oracle 客户端。一个应用程序不太可能只与一个 Oracle Client 版本一起工作。在一台机器上同时安装 32 位和 64 位也是一个好方法,请按照以下说明进行操作:Install Oracle x86 and X64 on one machine
如果您确实需要使用不同的 Oracle Client 版本测试您的应用程序,请设置几台测试 PC(可能在 Virtual-Box 中),每台都具有不同的 Client 版本。否则处理起来会非常困难。
更新:
我认为每个(非托管)ODP.NET 版本仅适用于相应版本的 Oracle 客户端。也许偶然有一些组合可以解决问题,但通常版本应该匹配。
我看到两种不同的解决方案:
(1) 要求您的客户安装他的 Oracle 客户端,包括 ODP.NET。他可以选择版本,只有架构(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) 在您的设置中 script/exe 确定客户安装的 Oracle 客户端的版本并根据 ODP.NET 复制到客户机器。
为了确定 Oracle 客户端的版本,您可以在 PATH
环境提供的文件夹中搜索文件 oci.dll
。 oci.dll
是一个普通的.NET程序集,所以你可以很容易地读出版本。
要正确安装 ODP.NET,请遵循下载的 ODP.NET XCopy 版本中的文件 configure.bat
。在我看来,这个批处理文件很容易理解。
基本上是这样
1 - 将文件 Oracle.DataAccess.dll
复制到目标机器
2 - 复制不同的资源文件*\Oracle.DataAccess.resources.dll
到目标机器
3 - 将这些 DLL 添加到 GAC。这可以通过 gacutil.exe
或 OraProvCfg.exe
(包含在下载器 ZIP 文件中)或您的安装应用程序提供此操作来完成。
4 - 创建一些 Registy 条目。较新的 ODP.NET 版本 write/read 变成 HKLM\SOFTWARE\Wow6432Node\Oracle\ODP.NET
(对于 32 位),resp。 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 位)而不是
就是这样,您应该可以将其包含在您的设置中。
你知道,我只花了 5 分钟寻找那个我记得以前尝试过这个的人......结果证明是你肖恩 ;)。
老实说,依靠客户端安装的东西是废话。我会使用完整的 xcopy 包,让它工作,然后向后工作,删除不需要的东西。
- 不要运行自带的install.bat。这样做会添加有助于定位非托管二进制文件的注册表项,但您也有可能弄乱客户端安装的副本。
- 将整个 xcopy 安装作为子文件夹拖放到应用程序的文件夹中。
- 相反,将 DllPath 设置为此新的子文件夹
示例:
<oracle.dataaccess.client>
<settings>
<add name="DllPath" value="C:\app\user\product.1.0\client_1\BIN"/>
- 然后设置Oracle_Home环境变量
示例:
Environment.SetEnvironmentVariable("ORACLE_HOME", @"C:\app\user\product.1.0\client_1\");
这篇文章做了类似的事情:
http://dbaportal.eu/2013/02/22/true-xcopy-runtime-for-oracle-odp-net-application/
他甚至添加了重定向策略,以防他引用了引用特定版本 Oracle.DataAccess.dll
的项目
不过,他用一个批处理文件添加了他的 oracle home。我不太确定的部分是他还将他的新 xcopy 安装添加到具有相同批处理文件的路径中。 DllPath 应该会处理这个问题,但如果我错了,你也可以在 运行 时间:
Environment.SetEnvironmentVariable("PATH", @"C:\app\user\product.1.0\client_1\BIN");
从这里开始,我将使用您正在使用的所有 ODP.net 功能设置一些基本单元测试并获得一些积极的测试,然后向后工作 - 开始删除您不需要的内容,运行每次都测试你的测试。您可以使用 sysinternals procexp 来显示加载的 dll(或使用 procmon 来显示对文件的访问)。只需加载测试就足以锁定文件,这样您就可以删除所有未锁定的文件。
我不确定是否支持这样做。然后 Oracle 再次在非托管搜索顺序中列出 "the current application's directory",因此他们也没有关门。
编辑:
找到其他人这样做的链接之一:
http://alderprogs.blogspot.com/2009/04/deploying-odpnet-with-oracle-instant.html
我不确定为什么,但他们单独下载了即时客户端(它已经是 xcopy 包的一部分)。
编辑 2016 年 4 月 15 日:如果您最近正在阅读本文,请注意两点。 1) 如果您已经设置了 DllPath,我认为没有必要设置环境变量。 2) 当托管提供程序现在只需要一个或两个 dll 时,我认为这样做不值得。
我的机器上安装了 oracle 10g 客户端(完整版)和 11g 即时客户端。 我正在尝试使用 ODP.NET 12c。这是我所做的。
- 已将 Oracle.DataAccess.dll 添加到参考文献。
- 复制OraOps12.dll到我的可执行文件所在的文件夹。
当运行我得到了"Unable to load DLL 'OraOps12.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"。
我认为这可能是由于依赖性问题。所以我进一步复制了12c的
- oci.dll
- oraociei12.dll
- orannzsbb12.dll
然后我仍然遇到其他依赖性错误。不过,我不想复制整个 InstantClient。
我的目标是让应用程序与其他版本的 Oracle 客户端一起使用。 我们的客户安装了不同版本的 Oracle 客户端。那么有什么方法可以让应用程序 (ODAC12c) 与客户当前版本的 Oracle 客户端一起工作而无需安装 12c 客户端?
谢谢,
更新: 忘了说几件事
我的 ODAC 是 32 位的,我在 x86 上编译了我的应用程序。
我没有使用 Oracle.ManagedDataAccess.dll 因为它不包含 BULKCOPY classs。如果有人知道包含 bulkcopy class 的 Oracle.ManagedDataAccess.dll 版本,请告诉我。
我们的客户已经为其他应用程序安装了不同版本的 Oracle 客户端,他们不想仅仅为了这个新应用程序而改变他们的环境。所以我的目标是让我的应用程序中的一个版本的 ODAC 与不同版本的现有 Oracle 客户端一起工作(每个客户环境都不同)。这可能吗?如果可能,怎么办?
将单个 DLL 复制到不同的目录并希望它能工作是个坏主意。
通常 ODP.NET 提供程序只能与相应的 Oracle Client 一起工作,即为了使用 ODP.NET 12,您还必须安装 Oracle Client 12。同样适用于版本 11 或 10。 唯一的例外是 ODP.NET Managed Driver,在那里你只需要一个 DLL (Oracle.ManagedDataAccess.dll).
此外,体系结构(32 位与 64 位)必须匹配。
如果您使用 OLEDB 提供程序,则甚至不可能安装多个提供程序(针对每个体系结构)- 除非您一直通过操纵 PATH
变量和注册表来破解您的系统。
我的建议是:从您的计算机中删除所有 Oracle 客户端,并仅正确安装 一个(或每个体系结构一个)Oracle 客户端。一个应用程序不太可能只与一个 Oracle Client 版本一起工作。在一台机器上同时安装 32 位和 64 位也是一个好方法,请按照以下说明进行操作:Install Oracle x86 and X64 on one machine
如果您确实需要使用不同的 Oracle Client 版本测试您的应用程序,请设置几台测试 PC(可能在 Virtual-Box 中),每台都具有不同的 Client 版本。否则处理起来会非常困难。
更新:
我认为每个(非托管)ODP.NET 版本仅适用于相应版本的 Oracle 客户端。也许偶然有一些组合可以解决问题,但通常版本应该匹配。
我看到两种不同的解决方案:
(1) 要求您的客户安装他的 Oracle 客户端,包括 ODP.NET。他可以选择版本,只有架构(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) 在您的设置中 script/exe 确定客户安装的 Oracle 客户端的版本并根据 ODP.NET 复制到客户机器。
为了确定 Oracle 客户端的版本,您可以在 PATH
环境提供的文件夹中搜索文件 oci.dll
。 oci.dll
是一个普通的.NET程序集,所以你可以很容易地读出版本。
要正确安装 ODP.NET,请遵循下载的 ODP.NET XCopy 版本中的文件 configure.bat
。在我看来,这个批处理文件很容易理解。
基本上是这样
1 - 将文件 Oracle.DataAccess.dll
复制到目标机器
2 - 复制不同的资源文件*\Oracle.DataAccess.resources.dll
到目标机器
3 - 将这些 DLL 添加到 GAC。这可以通过 gacutil.exe
或 OraProvCfg.exe
(包含在下载器 ZIP 文件中)或您的安装应用程序提供此操作来完成。
4 - 创建一些 Registy 条目。较新的 ODP.NET 版本 write/read 变成 HKLM\SOFTWARE\Wow6432Node\Oracle\ODP.NET
(对于 32 位),resp。 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 位)而不是
就是这样,您应该可以将其包含在您的设置中。
你知道,我只花了 5 分钟寻找那个我记得以前尝试过这个的人......结果证明是你肖恩 ;)。
老实说,依靠客户端安装的东西是废话。我会使用完整的 xcopy 包,让它工作,然后向后工作,删除不需要的东西。
- 不要运行自带的install.bat。这样做会添加有助于定位非托管二进制文件的注册表项,但您也有可能弄乱客户端安装的副本。
- 将整个 xcopy 安装作为子文件夹拖放到应用程序的文件夹中。
- 相反,将 DllPath 设置为此新的子文件夹
示例:
<oracle.dataaccess.client>
<settings>
<add name="DllPath" value="C:\app\user\product.1.0\client_1\BIN"/>
- 然后设置Oracle_Home环境变量
示例:
Environment.SetEnvironmentVariable("ORACLE_HOME", @"C:\app\user\product.1.0\client_1\");
这篇文章做了类似的事情: http://dbaportal.eu/2013/02/22/true-xcopy-runtime-for-oracle-odp-net-application/
他甚至添加了重定向策略,以防他引用了引用特定版本 Oracle.DataAccess.dll
的项目不过,他用一个批处理文件添加了他的 oracle home。我不太确定的部分是他还将他的新 xcopy 安装添加到具有相同批处理文件的路径中。 DllPath 应该会处理这个问题,但如果我错了,你也可以在 运行 时间:
Environment.SetEnvironmentVariable("PATH", @"C:\app\user\product.1.0\client_1\BIN");
从这里开始,我将使用您正在使用的所有 ODP.net 功能设置一些基本单元测试并获得一些积极的测试,然后向后工作 - 开始删除您不需要的内容,运行每次都测试你的测试。您可以使用 sysinternals procexp 来显示加载的 dll(或使用 procmon 来显示对文件的访问)。只需加载测试就足以锁定文件,这样您就可以删除所有未锁定的文件。
我不确定是否支持这样做。然后 Oracle 再次在非托管搜索顺序中列出 "the current application's directory",因此他们也没有关门。
编辑: 找到其他人这样做的链接之一: http://alderprogs.blogspot.com/2009/04/deploying-odpnet-with-oracle-instant.html
我不确定为什么,但他们单独下载了即时客户端(它已经是 xcopy 包的一部分)。
编辑 2016 年 4 月 15 日:如果您最近正在阅读本文,请注意两点。 1) 如果您已经设置了 DllPath,我认为没有必要设置环境变量。 2) 当托管提供程序现在只需要一个或两个 dll 时,我认为这样做不值得。