[Oracle] Win10 で ODP.NET 11.2 を使用したプログラムをリビルドなしで動作させる

2020年7月26日

 Windows 7 + Oracle 11gR2 時代のプログラムをリビルドすることなく Windows 10 で動作させたいのですが、ODP.NET の 11.2 は Windows 10 非対応です。そこで Windows 10 対応の ODAC を使い、ODP 11.2 のプログラムを動作させるための設定を行ってみました。

  1. Oracle ODAC Xcopy のインストール

     まず Oracle ODAC のインストールを行います。
     Windows 10 で動作させたいので、Windows 10 対応されている ODAC のうち今回は 18.3 を使用することにします。

    1. 「ODAC Runtime Downloads」で検索し、https://www.oracle.com/database/technologies/dotnet-odacdeploy-downloads.html にアクセスします。

    2. 下にスクロールさせていくと、ODAC Xcopy というセクションがあります。ここで任意のバージョンのランタイムを取得します。今回は 32bit の ODAC 18.3 を選択します。
    3. C++ 再頒布可能パッケージ をダウンロードします。

       ODAC をインストールするためには、バージョンに対応した C++ 再頒布可能パッケージが必要です。
       下にスクロールさせていくとリンクがあるので、対応したバージョンの C++ 再頒布可能パッケージ を Microsoft のサイトからダウンロードします。
       今回は 18.3 なので 2013 の C++ 再頒布可能パッケージ をダウンロードします。
       (以前の記事「Instant Client のインストール (11.2 for Windows)」ではこの記載がありませんが、この時の環境は Visual Studio がすでにインストールされた環境であったため、あらためてインストールする必要がなかったのだと思われます・・・ -_-;)

    4. リンク先に「Microsoft Visual C++ Redistributable Packages for Visual Studio 2013」があるのでそれを選択します。
    5. ダウンロードした C++ 再頒布可能パッケージをインストールします。
    6. ダウンロードした ODAC Runtime を解凍しインストールします。

       インストール先と Oracle Home 名は自由に設定できます。今回は c:\oracle\product\18.3\odac、Oracle Home 名は odac183 にします。
       また、ODP.NET 2 と ODP.NET 4 をインストールするので、以下のように 2 回インストーラーを実行します。
       また、コマンドプロンプトは管理者で実行し、ODAC Xcopy を解凍したディレクトリをカレントにおいておきます。

      C> install.bat odp.net2 c:\oracle\product\18.3\odac odac183 true
      C> install.bat odp.net4 c:\oracle\product\18.3\odac odac183 true
      

    7. インストールが終了すると、Path に定義を先頭に追加します。
      C:\oracle\Product\18.3\odac
      C:\oracle\Product\18.3\odac\bin
      

       ちなみに上記の画面キャプチャだと 3 行目に C:\oracle\Product\18.0.0\dbhomeXE\bin というのがいますが、ここれはインストール PC に Oracle XE 18c をインストールしていたためで、今回の作業とは関係ありません。

    8. インストール先にある oracle.key を参照し、レジストリを変更します。
    9. 接続先データベースの NLS_LANG にあわせます。今回は Oracle XE に接続こともあり、NLS_LANG を JAPANESE_JAPAN.AL32UTF8 に変更します。
    10. 接続先を TNSNAMES.ORA に設定します。

       本来は C:\oracle\product\18.3\odac\network\admin\ に tnsnames.ora を書くべきですが、今回の PC には Oracle XE がインストールされていた手前、二重管理が面倒なので XE 側の tnsnames.ora にリンクを貼ることでお茶を濁します(汗

      C> mklink C:\oracle\product\18.3\odac\network\admin\tnsnames.ora C:\oracle\product\18.0.0\dbhomeXE\network\admin\tnsnames.ora
      
  2. ODP.NET 11.2 のリダイレクト設定

     次に ODP.NET 11.2 のプログラムが ODP.NET 18.3 の Oracle.DataAccess.dll をロードするための設定を行います。
     また以下では Oracle Home ディレクトリを %ORACLE_HOME% と表現しています。今回の場合は上記インストールで指定した c:\oracle\product\18.3\odac になります。

    1. GAC に 18.3 の Oracle.DataAccess.dll を登録します。

       .net2 用, .net4用の Oracle.DataAccess.dll を GAC に登録します。
       Oracle.DataAccess.dll の場所は %ORACLE_HOME%\odp.net\bin です。
       その際、OraProvCfg.exe を使用しますが、ファイル名は同じですが中身は .net2 用, .net4用で異なるようなので、それぞれのフォルダにある OraProvCfg.exe を使用します。

      C> C:\oracle\product\18.3\odac\odp.net\bin\2.x\OraProvCfg.exe /action:gac /providerpath:C:\oracle\product\18.3\odac\odp.net\bin\2.x\Oracle.DataAccess.dll
      C> C:\oracle\product\18.3\odac\odp.net\bin\4\OraProvCfg.exe /action:gac /providerpath:C:\oracle\product\18.3\odac\odp.net\bin\4\Oracle.DataAccess.dll
      
    2. 11.2 用の発行者ポリシーを GAC に登録します。

       .net2 用, .net4用の Policy.2.112.Oracle.DataAccess.dll を GAC に登録します。
       Policy.2.112.Oracle.DataAccess.dll の場所は %ORACLE_HOME%\odp.net\PublisherPolicy です。
       その際、OraProvCfg.exe を使用しますが、ファイル名は同じですが中身は .net2 用, .net4用で異なるようなので、それぞれのフォルダにある OraProvCfg.exe を使用します。

      C> C:\oracle\product\18.3\odac\odp.net\bin\2.x\OraProvCfg.exe /action:gac /providerpath:C:\oracle\product\18.3\odac\odp.net\PublisherPolicy\2.x\Policy.2.112.Oracle.DataAccess.dll
      C> C:\oracle\product\18.3\odac\odp.net\bin\4\OraProvCfg.exe /action:gac /providerpath:C:\oracle\product\18.3\odac\odp.net\PublisherPolicy\4\Policy.4.112.Oracle.DataAccess.dll
      
  3. セットアップ失敗事例

     以下のようなエラーが表示された場合、セットアップに失敗しているかもしれません。

    1. GAC に登録していない

       「ファイルまたはアセンブリ、またはその依存関係の 1 つが読み込めませんでした。」が表示される場合、GAC への Oracle.DataAccess.dll 本体または発行者ポリシー(Policy.X.XXX.Oracle.DataAccess.dll)の登録に失敗しているかもしれません。

      ハンドルされていない例外: System.IO.FileNotFoundException: ファイルまたはアセンブリ 'Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見 つかりません。
         場所 ConsoleApplication1.Module1.Main()
      
    2. 64bit の DLL をロードしている

       「間違ったフォーマットのプログラムを読み込もうとしました。」が表示される場合、違うプラットフォームの DLL を読み込んでいる可能性があります。今回の場合は 32 bit の DLL をロードするはずが 64 bit の DLL をロードしている可能性があります。GAC に登録した DLL のプラットフォーム(32bit or 64bit)や Path の登録, 順序等を再確認してください。

      ハンドルされていない例外: System.TypeInitializationException: 'Oracle.DataAccess.Client.OracleConnection' のタイプ初期化子 が例外をスローしました。 ---> System.BadImageFormatException: 間違ったフォーマットのプログラムを読み込もうとしました。 (HRESULT からの例外:0x8007000B)
         場所 Oracle.DataAccess.Client.OpsInit.CheckVersionCompatibility(String version)
         場所 Oracle.DataAccess.Client.OracleInit.Initialize()
         場所 Oracle.DataAccess.Client.OracleConnection..cctor()
         --- 内部例外スタック トレースの終わり ---
         場所 Oracle.DataAccess.Client.OracleConnection..ctor(String connectionString)
      
    3. C++ 再頒布可能パッケージをインストールしていない。

       「'OraOpsXX.dll' を読み込めません:指定されたモジュールが見つかりません」が表示される場合、C++ 再頒布可能パッケージ をインストールしていないか、違うバージョンをインストールしている可能性があります。インストールした C++ 再頒布可能パッケージがインストールした ODAC が指定したバージョンと同じかどうかを確認してください。

      ハンドルされていない例外: System.TypeInitializationException: 'Oracle.DataAccess.Client.OracleConnection' のタイプ初期化子 が例外をスローしました。 ---> System.DllNotFoundException: DLL 'OraOps12.dll' を読み込めません:指定されたモジュールが見つかりません。 (HRESULT からの例外:0x8007007E)
         場所 Oracle.DataAccess.Client.OpsInit.CheckVersionCompatibility(String version)
         場所 Oracle.DataAccess.Client.OracleInit.Initialize()
         場所 Oracle.DataAccess.Client.OracleConnection..cctor()
         --- 内部例外スタック トレースの終わり ---
         場所 Oracle.DataAccess.Client.OracleConnection..ctor(String connectionString)
      
    4. Path が設定されていない

       「オブジェクト参照がオブジェクトインスタンスに設定されていません。」が表示される場合、%ORACLE_HOME% および %ORACLE_HOME%\bin への PATH が設定されていない可能性があります。PATH の定義を確認してください。

      ハンドルされていない例外: System.NullReferenceException: オブジェクト参照がオブジェクト イ ンスタンスに設定されていません。
         場所 Oracle.DataAccess.Client.OracleException.get_Number()
         場所 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable, OracleLogicalTransaction m_OracleLogicalTransaction)
         場所 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src, OracleLogicalTransaction m_oracleLogicalTransaction)
         場所 Oracle.DataAccess.Client.OracleConnectionOCP.Open(OracleConnection con)
         場所 Oracle.DataAccess.Client.OracleConnection.Open()
      
    5. tnsnames.ora がない

       「TNS: 指定された接続識別子を解決できませんでした」が表示される場合、%ORACLE_HOME%network\admin\ に tnsnames.ora が作成されていない可能性があります。当該フォルダに tnsnames.ora が存在するかを確認してください。また作成していた場合、指定した接続識別子のエントリーが記載しているかを確認してください。

      ハンドルされていない例外: Oracle.DataAccess.Client.OracleException: ORA-12154: TNS: 指定された接続識別子を解決できませんで した
         場所 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable, OracleLogicalTransaction m_OracleLogicalTransaction)
         場所 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src, OracleLogicalTransaction m_oracleLogicalTransaction)
         場所 Oracle.DataAccess.Client.OracleConnectionOCP.Open(OracleConnection con)
         場所 Oracle.DataAccess.Client.OracleConnection.Open()
      
    6. tnsnames.ora に誤り

       「ORA-12545: ターゲット・ホストまたはオブジェクトが存在しないため、接続に失敗しました」が表示される場合、%ORACLE_HOME%network\admin\tnsnames.ora の定義内容に誤りがある可能性があります。定義内容を再確認してください。

      ハンドルされていない例外: Oracle.DataAccess.Client.OracleException: ORA-12545: ターゲット・ホストまたはオブジェクトが存在しないため、接続に失敗しました
         場所 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable, OracleLogicalTransaction m_OracleLogicalTransaction)
         場所 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src, OracleLogicalTransaction m_oracleLogicalTransaction)
         場所 Oracle.DataAccess.Client.OracleConnectionOCP.Open(OracleConnection con)
         場所 Oracle.DataAccess.Client.OracleConnection.Open()
      





カテゴリー: Oracle

Follow comments via the RSS Feed | Leave a comment | Trackback URL

1 Comment to "[Oracle] Win10 で ODP.NET 11.2 を使用したプログラムをリビルドなしで動作させる"

  1. ooltcloud

    関連記事> Powershell で ODP.NET を使用して Oracle にアクセス
    http://ooltcloud.sakura.ne.jp/blog/201301/article_11003917.html

    関連記事> Instant Client のインストール (11.2 for Windows)
    http://ooltcloud.sakura.ne.jp/blog/201712/article_08232700.html

コメントを投稿する

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


«   »
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org