我的机器上安装了oracle 10g客户端(完整版)和11g即时客户端。 我正在尝试使用ODP.NET 12c。这就是我所做的。
运行时我得到“无法加载DLL'OraOps12.dll':找不到指定的模块。(HRESULT异常:0x8007007E)”。
我认为这可能是由于依赖性问题。所以我进一步复制了12c的
然后我还有其他依赖错误。我不想复制整个InstantClient。
我的目标是让应用程序与其他版本的Oracle客户端一起使用。 我们的客户安装了不同版本的Oracle客户端。那么任何方式让应用程序(ODAC12c)与客户当前版本的Oracle客户端一起工作而无需安装12c客户端?
谢谢,
更新: 我忘了提几件事
我的ODAC是32位,我在x86上编译了我的应用程序。
我没有使用Oracle.ManagedDataAccess.dll,因为它不包含BULKCOPY类。如果有人知道包含批量复制类的Oracle.ManagedDataAccess.dll版本,请告诉我。
我们的客户已经为其他应用程序安装了不同版本的Oracle客户端,他们不想仅为这个新应用程序更改其环境。所以我的目标是让我的应用程序中的一个版本的ODAC与不同版本的现有Oracle客户端一起工作(每个客户环境都不同)。这是可能的,如果可以,怎么样?
答案 0 :(得分:3)
你知道,我只花了5分钟寻找那个我记得曾经尝试过这个的人......结果证明你是肖恩;)。
老实说,依靠客户安装的东西是垃圾邮件。我会使用完整的xcopy包,让它工作,然后向后工作,删除不需要的东西。
示例:
<oracle.dataaccess.client>
<settings>
<add name="DllPath" value="C:\app\user\product\11.1.0\client_1\BIN"/>
示例:
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 home。我不太确定的部分是他还将新的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时,我认为这不值得做。
答案 1 :(得分:1)
将单个DLL复制到不同的目录并希望它能够正常工作是个坏主意。
通常,ODP.NET提供程序只能与相应的Oracle Client一起使用,即为了使用ODP.NET 12,您还必须安装Oracle Client 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(可能在虚拟盒中)。否则处理它将是非常具有挑战性的。
<强>更新强>
我认为每个(非托管)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客户端的版本,您可以在oci.dll
环境提供的文件夹中搜索文件PATH
。 oci.dll
是一个普通的.NET程序集,因此您可以轻松地读出该版本。
要正确安装ODP.NET,请遵循文件configure.bat
,该文件是下载的ODP.NET XCopy版本的一部分。在我看来,这个批处理文件很容易理解。
基本上它确实
1 - 将文件Oracle.DataAccess.dll
复制到目标计算机
2 - 将不同的资源文件*\Oracle.DataAccess.resources.dll
复制到目标machen
3 - 将这些DLL添加到GAC。这可以通过gacutil.exe
或OraProvCfg.exe
(包含在下载程序ZIP文件中)完成,或者您的安装应用程序提供此操作。
4 - 制作一些Regristy条目。较新的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位),resp HKLM\SOFTWARE\Wow6432Node\Oracle\KEY_{ORACLE_HOME_KEY}\ODP.NET\
(对于32位)而不是
就是这样,你应该可以在你的设置中包含它。