5

これが私のサンプルシナリオです。コンソール アプリケーションとクラス ライブラリ 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 が最終的に決定しているように見えます。アプリケーションが爆発することを保証します。:)

4

2 に答える 2

5

それを参照しないことで、暗黙のルールを使用できるようになります。ほとんどのdll は GAC にないため、ここでの暗黙のデフォルトは「ローカルにコピー」です。IDE には、デフォルトで「動作させる」というクレイジーな概念があります。これは、「GAC にはないと仮定する」ことを意味します。

明示的なルールを使用する場合は、はい: 必要なものを指定する必要があります。その方法は、参照を追加してから、必要なオプションを設定することです。

于 2013-02-17T17:26:15.287 に答える
0

私が取り組んでいるソリューションで同じ問題と思われるものについて十分な調査を行った結果、この問題は、.NET 4.5 のリリースで導入された新しいチェックが原因であることがわかりました : ビルド時に、プロセッサ タイプがプロジェクトのものと一致することを確認するために、参照がチェックされるようになりました。

以前はビルド ログにそのようなエラーは表示されませんでしたが、影響を受けるマシンでは、すべての CPU 用にビルドされた 1 つの DLL を使用可能にするのではなく、プロジェクトが MSIL 用にビルドされ、DLL が x86 用にビルドされていることを示すメッセージが表示されるようになりました。サードパーティの作成者は、x86 と x64 用に 2 つの個別の DLL を提供しており、どちらも GAC に含まれています。このチェックが導入される前は、システムは GAC の DLL を使用して適切なバージョンを選択していましたが、.NET 4.5 をインストールした後、ビルド プロセスは GAC のどちらのバージョンも受け入れられないと判断したようです。ローカルコピー。

この動作を無効にする方法を特定できていないため、解決オプションは、ビルド後のイベントを追加してローカル コピーを削除するか、(質問で述べたように) 参照を追加する必要があります。 「Library A」を参照するすべてのプロジェクトに問題のDLLを追加し、それらの参照を「copy local = false」に設定します。これにより、動作していないローカルバージョンが出力にコピーされるのを防ぐようです。

于 2015-01-22T14:21:45.480 に答える