これが私のサンプルシナリオです。コンソール アプリケーションとクラス ライブラリ dll (libraryA と呼びます) があります。LibraryA dll には、Oracle.DataAccess.dll バージョン 4.112.2.0 への参照があります。Oracle DLL は GAC にあります。LibraryA の Oracle DLL への参照は、"Copy Local = false" です。ここまでは順調ですね。libraryA dll をビルドすると、Oracle.DataAccess.dll は出力ディレクトリに表示されません。わかった。ここで、コンソール アプリで libraryA dll を参照します。libraryA dll への参照は「copy local = true」です。ここで、コンソール アプリケーションをビルドすると、コンソール アプリケーションの出力ディレクトリにOracle.DataAcess.dllが表示されます。ただし、このように動作する唯一の DLL は Oracle dll のようです。LibraryA の完全なコードは次のとおりです。
public void Foo() {
Oracle.DataAccess.Client.OracleConnection c = new Oracle.DataAccess.Client.OracleConnection();
WebMatrix.WebData.OAuthAccountData x = new WebMatrix.WebData.OAuthAccountData("asd", "asd");
DevExpress.Web.ASPxCallback.ASPxCallback cvv = new DevExpress.Web.ASPxCallback.ASPxCallback();
}
WebMatrix と DevExpress も、Oracle DLL と同様に GAC に含まれています。ただし、これらの DLL はどちらも出力ディレクトリに出力されず、Oracle dll のみが出力されます。なぜですか?ここで何が起こっているのですか?
さらに言えば、別のクラス ライブラリを作成し、それを libraryB と呼び、libraryB を GAC に配置しないでください。LibraryA から LibraryB を参照し、copy local = false に設定します。その場合でも、libraryB はコンソール アプリの出力ディレクトリにコピーされません。もちろん、この場合、ライブラリ B が見つからないため、プログラムは失敗しますが、少なくとも Visual Studio は copy local flag = false を尊重しています。このばかげた Oracle DLL の違いは何ですか?
あ、もう一つ面白い。コンソール アプリケーションで明示的に Oracle.DataAccess.dll への参照を追加し、copy local = false と指定すると、出力ディレクトリに表示されません。出力ディレクトリにDLLが表示されないようにするために、実際に参照する必要があるのはちょっとばかげているようです:)
編集:
もう一つの手がかり。Oracle は、開発者を苦しめるために、AnyCPU 用にビルドされた DLL を 1 つも持っていません。x86 バージョンと x64 バージョンがあります。私の場合、x86 バージョンを参照し、AnyCPU 用にビルドしています。ただし、(oracle dll と一致するように) x86用にビルドすると、Oracle DLLは出力ディレクトリにコピーされます。AnyCPU でビルドする場合、MSBUILD は次のように述べています。 PublicKeyToken=89b483f429c47342, processorArchitecture=x86", "x86". この不一致により、ランタイム エラーが発生する可能性があります。プロジェクトと参照の間でプロセッサ アーキテクチャを調整するために、Configuration Manager を使用してプロジェクトのターゲット プロセッサ アーキテクチャを変更することを検討してください。プロジェクトのターゲット プロセッサ アーキテクチャと一致するプロセッサ アーキテクチャの参照への依存。」つまり、Msbuild が最終的に決定しているように見えます。アプリケーションが爆発することを保証します。:)