292

私の Visual Studio ソリューションには 4 つのプロジェクトがあります (全員が .NET 3.5 を対象としています)。私の問題では、次の 2 つだけが重要です。

  1. MyBaseProject <- このクラス ライブラリは、サードパーティの DLL ファイル (elmah.dll) を参照します。
  2. MyWebProject1 <- この Web アプリケーション プロジェクトには MyBaseProject への参照があります

「参照の追加...」→「参照」タブ→「elmah.dll」を選択して、Visual Studio 2008のMyBaseProjectへのelmah.dll参照を追加しました。

Elmah 参照のプロパティは次のとおりです。

  • エイリアス - グローバル
  • ローカルにコピー - true
  • 文化 -
  • 説明 - ASP.NET のエラー ログ モジュールとハンドラー (ELMAH)
  • ファイルの種類 - アセンブリ
  • パス - D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
  • 解決済み - 真
  • ランタイム バージョン - v2.0.50727
  • 指定されたバージョン - false
  • 厳密な名前 - false
  • バージョン - 1.0.11211.0

MyWebProject1で、「参照の追加...」→「プロジェクト」タブ→「MyBaseProject」を選択して、プロジェクト MyBaseProject への参照を追加しましたこの参照のプロパティは、次のメンバーを除いて同じです。

  • 説明 -
  • パス - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
  • バージョン - 1.0.0.0

Visual Studioでビルドを実行すると、elmah.dll ファイルがMyWebProject1 の binディレクトリに MyBaseProject.dll と共にコピーされます。

ただし、ソリューションのMSBuildをクリーンアップして実行すると(D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln 経由) ) elmah.dll がMyWebProject1 の bin ディレクトリにありません - ビルド自体には警告やエラーは含まれていません!

MyBaseProject の .csproj に、値が「true」のプライベート要素が含まれていることを確認しました (これは、Visual Studioの「 copy local 」のエイリアスである必要があります)。

<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
    **<Private>true</Private>**
</Reference>

(プライベート タグは、既定では .csproj の xml に表示されませんでしたが、Visual Studio は "ローカルのコピー" を true と表示しました。"ローカルのコピー" を false に切り替えて保存し、再度 true に戻して保存します!)

MSBuild の何が問題になっていますか? (elmah.dll) 参照を MyWebProject1 のビンにコピーするにはどうすればよいですか?

すべてのプロジェクトのビルド後のコマンドにビルド後のコピー アクションを追加したくありません。(MyBaseProject に依存する多くのプロジェクトがあると想像してください!)

4

20 に答える 20

171

このように対処するだけです。参照のプロパティに移動して、次の操作を行います。

Set "Copy local = false"
Save
Set "Copy local = true"
Save

以上です。

Visual Studio 2010 は、最初 <private>True</private> は参照タグに: を配置せず、"copy local" を false に設定すると、タグが作成されます。その後、それに応じて true と false に設定されます。

于 2011-10-21T23:54:33.953 に答える
167

Visual Studio と MsBuild の間でビルドするときになぜ異なるのかはわかりませんが、MsBuild と Visual Studio でこの問題に遭遇したときに見つけたものを次に示します。

説明

サンプル シナリオとして、プロジェクト X、アセンブリ A、およびアセンブリ B があるとします。アセンブリ A はアセンブリ B を参照するため、プロジェクト X には A と B の両方への参照が含まれます。また、プロジェクト X には、アセンブリ A を参照するコードが含まれます (たとえば、A. SomeFunction())。ここで、プロジェクト X を参照する新しいプロジェクト Y を作成します。

したがって、依存チェーンは次のようになります: Y => X => A => B

Visual Studio / MSBuild は賢く、プロジェクト X に必要であると検出された参照のみをプロジェクト Y に持ち込もうとします。これは、プロジェクト Y での参照汚染を回避するために行われます。問題は、プロジェクト X にはアセンブリ B を明示的に使用するコード (B.SomeFunction() など) が実際には含まれていないため、VS/MSBuild は B が必要であることを検出しないことです。したがって、プロジェクト Y の bin ディレクトリにコピーしません。X および A アセンブリのみをコピーします。

解決

この問題を解決するには 2 つの方法があります。どちらの方法でも、アセンブリ B がプロジェクト Y の bin ディレクトリにコピーされます。

  1. プロジェクト Y のアセンブリ B への参照を追加します。
  2. アセンブリ B を使用するプロジェクト X のファイルにダミー コードを追加します。

個人的には、いくつかの理由からオプション 2 を好みます。

  1. 将来、プロジェクト X を参照する別のプロジェクトを追加する場合、アセンブリ B への参照も含めることを忘れないでください (オプション 1 で行う必要があるように)。
  2. ダミーコードが必要な理由を明示的にコメントして、それを削除しないようにすることができます。そのため、誰かが誤ってコードを削除した場合 (未使用のコードを探すリファクタリング ツールなど)、ソース管理からそのコードが必要であることを簡単に確認して、それを復元することができます。オプション 1 を使用し、誰かがリファクタリング ツールを使用して未使用の参照をクリーンアップした場合、コメントはありません。参照が .csproj ファイルから削除されたことがわかります。

これは、この状況に遭遇したときに通常追加する「ダミー コード」のサンプルです。

    // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
    private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
    {
        // Assembly A is used by this file, and that assembly depends on assembly B,
        // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
        // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
        // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
        // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
        var dummyType = typeof(B.SomeClass);
        Console.WriteLine(dummyType.FullName);
    }
于 2014-01-10T22:30:17.493 に答える
39

アセンブリをコードで直接使用していない場合、Visual Studioは役立つように努めているときに、アセンブリが使用されていないことを検出し、出力に含めません。VisualStudioとMSBuildで異なる動作が見られる理由がわかりません。ビルド出力を両方の診断に設定してみて、結果を比較して、どこで分岐するかを確認できます。

elmah.dll参照については、コードで直接参照していない場合は、プロジェクトにアイテムとして追加し、ビルドアクションをに設定し、Content出力ディレクトリにコピーをに設定できますAlways

于 2009-07-16T15:05:44.467 に答える
16

を見てみましょう:

私が始めたこのMSBuildフォーラムスレッド

あなたは私の一時的な解決策/回避策をそこに見つけるでしょう!

(MyBaseProjectには、myWebProject1のbinにコピーされるelmah.dllのelmah.dllからいくつかのクラス(何でも)を参照するコードが必要です!)

于 2009-07-16T10:32:53.460 に答える
9

私も同じ問題を抱えていました。

プロジェクトのフレームワーク バージョンが、参照した dll のフレームワーク バージョンと同じかどうかを確認します。

私の場合、クライアントは「Framework 4 Client」を使用してコンパイルされ、DLL は「Framework 4」にありました。

于 2012-01-23T13:40:26.110 に答える
8

私が直面していた問題は、ライブラリ プロジェクトに依存するプロジェクトがあることでした。ビルドするために、次の手順に従っていました。

msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package

もちろん、それはライブラリのdllファイルがbinになく、最も重要なのはパッケージのzipファイルにないことを意味していました。私はこれが完全に機能することを発見しました:

msbuild.exe myproject.vbproj /T:Rebuild;Package

なぜこれが機能したのか、そもそもなぜ機能しなかったのか、私にはわかりません。しかし、それが役立つことを願っています。

于 2012-07-18T22:49:52.250 に答える
6

まったく同じ問題が発生しましたが、同じソリューション内の 2 つのプロジェクトがサードパーティ ライブラリの異なるバージョンを参照していることが原因であることが判明しました。

すべての参照を修正すると、すべてが完全に機能しました。

于 2014-02-12T15:24:53.353 に答える
6

Alex Burtsev がコメントで述べたように、XAML リソース ディクショナリでのみ使用されるもの、または私の場合、XAML でのみ使用され、コード ビハインドでは使用されないものは、MSBuild によって「使用中」とは見なされません。

そのため、コード ビハインドでアセンブリ内のクラス/コンポーネントへのダミー参照を新しく作成するだけで、アセンブリが実際に使用されていることを MSBuild に納得させることができました。

于 2013-08-14T00:38:34.597 に答える
5

デッドリードッグの策略を利用して、

Y => X => A => B

私の問題は、Y をビルドしたときに、X のアセンブリ (A と B、15 個すべて) が Y の bin フォルダーに表示されなかったことです。

Y から参照 X を削除し、保存、ビルドしてから、X 参照 (プロジェクト参照) を再度追加し、保存、ビルドすると、A と B が Y の bin フォルダーに表示されるようになりました。

于 2016-12-08T20:39:56.657 に答える
4

ターゲット フレームワークを.NET Framework 4 Client Profileから.NET Framework 4 に変更すると、この問題が解決されました。

したがって、あなたの例では: MyWebProject1 のターゲット フレームワークを.NET Framework 4に設定します。

于 2013-08-02T19:20:50.427 に答える
3

私は同じ問題を抱えていました.dllは動的にロードされた参照でした. この問題を解決するために、dll の名前空間に「using」を追加しました。これで、dll が出力フォルダーにコピーされます。

于 2012-06-27T09:39:57.400 に答える
3

ビルド中に使用されないアセンブリを参照することは、正しい方法ではありません。追加のファイルがコピーされるように、ビルド ファイルを拡張する必要があります。ビルド後のイベントを使用するか、プロパティ グループを更新します。

いくつかの例は、他の投稿で見つけることができます

于 2013-11-26T12:52:27.157 に答える
3

これが表示される別のシナリオは、Visual Studio で古い「Web サイト」プロジェクト タイプを使用している場合です。そのプロジェクトの種類の場合、独自のディレクトリ構造 (現在のフォルダー以下) の外部にある .dll を参照することはできません。上記の回答で、ディレクトリ構造が次のようになっているとします。

ここに画像の説明を入力

ProjectX と ProjectY は親/子ディレクトリであり、ProjectX は A.dll を参照し、B.dll は B.dll を参照し、B.dll はルート (パッケージ) の Nuget パッケージなどのディレクトリ構造の外にあります。 dll は含まれますが、B.dll は含まれません。

于 2017-03-20T18:19:29.670 に答える
2

今日も同様の問題がありましたが、これは間違いなくあなたの質問に対する答えではありません。しかし、私は皆さんにお知らせしたいと思います。

ASP.NET アプリケーションがあります。ビルド プロセスは、クリーンしてからビルドするように設定されています。

2 つのJenkins CIスクリプトがあります。1 つは本番用、もう 1 つはステージング用です。アプリケーションをステージングにデプロイしたところ、すべて正常に機能しました。本番環境にデプロイされ、参照された DLL ファイルがありませんでした。この DLL ファイルは、プロジェクトのルートにありました。どの NuGet リポジトリにもありません。DLL は に設定されましたdo not copy

CI スクリプトとアプリケーションは、2 つの展開で同じでした。ステージング環境でクリーンアップとデプロイを行った後も、ASP.NET アプリケーションのデプロイ場所で DLL ファイルが置き換えられました ( bin/)。これは、本番環境には当てはまりませんでした。

テスト ブランチで、この DLL ファイルをディレクトリにコピーするステップをビルド プロセスに追加したことが判明しましたbin。今、理解するのに少し時間がかかった部分。CI プロセス自体がクリーニングされていませんでした。DLL は作業ディレクトリに残され、誤って ASP.NET .zip ファイルにパッケージ化されていました。運用ブランチでは、同じ方法で DLL ファイルがコピーされたことはなく、誤ってこれをデプロイすることもありませんでした。

TLDR; ビルドサーバーが何をしているかを確認してください。

于 2016-03-19T10:19:39.843 に答える
1

Visual Studio 2015 を使用して追加パラメーターを追加する

/deployonbuild=false

msbuild コマンド ラインに追加すると、問題が修正されました。

于 2019-11-27T16:40:22.580 に答える
0

非常によく似た問題に遭遇しました。Visual Studio 2010 を使用してコンパイルすると、DLL ファイルがbinフォルダーに含まれていました。しかし、MSBuild を使用してコンパイルすると、サードパーティの DLL ファイルが含まれませんでした。

とてもイライラします。私がそれを解決した方法は、NuGet参照を Web プロジェクトで直接使用していなくても、パッケージへの参照を含めることでした。

于 2012-08-15T22:13:38.767 に答える