依存DLLがVisual Studioのビルド出力フォルダーにコピーされない


188

ビジュアルスタジオソリューションがあります。ソリューションには多くのプロジェクトがあります。スタートアップとして機能し、他のプロジェクトを使用する1つのメインプロジェクトがあります。「ProjectX」というプロジェクトが1つあります。その参照がメインプロジェクトに追加されます。ProjectXは、ソリューションの一部ではない別の.NET dll(たとえば、abc.dll)を参照します。

これで、このabc.dllはメインプロジェクトのbin / debugフォルダーにコピーされますが、そこにはコピーされません。既知の理由でコピーされないのはなぜですか?


これを理解できない場合は、プリビルドにコピーしてください。
Dilshod 2013

メインプロジェクトで「ProjectX」をどのように使用しますか-プロジェクトのタイプ、ターゲットなどは
何ですか

私は同じ問題を抱えていて、この回答で問題が解決しました:stackoverflow.com/a/8213977/174469
Gordon Tucker


そこでRestoreProjectStyle 利用できるソリューション。アイデアは<RestoreProjectStyle>PackageReference</RestoreProjectStyle>、ソリューションの.Net Frameworkプロジェクトごとに設定することです。
oleksa

回答:


105

ProjectXがabc.dllを参照しているが、abc.dllで定義されているタイプのいずれも直接使用しなかった場合、abc.dllはメイン出力フォルダーにコピーされないことがわかりました。(さらに混乱させるために、ProjectX出力フォルダーにコピーされます。)

したがって、ProjectXのどこかでabc.dllの型を明示的に使用していない場合は、ProjectXのいずれかのファイルのどこかにダミー宣言を配置します。

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied

すべてのクラスでこれを行う必要はありません-DLLコピーを作成するために1回で十分であり、すべてが期待どおりに機能します。

補遺:これはデバッグモードでは機能するかもしれませんが、リリースでは機能しないことに注意してください。詳細については、@ nvirthの回答を参照してください。


7
これはハックのようです。メインプロジェクトへの参照を追加するだけで十分なようです。
Mike K

3
それはハックですが、今日のCodeProjectニュースが教えてくれたように、コンパイラでさえ間違っている可能性があります!
オーバーロード

4
ものすごいことが起こりえます。@OverlordZurg私のXAML(WPF)に依存するdllへの参照があり、あなたが言ったように単純なダミー参照を追加するまでDLLをメインプロジェクトにコピーしなかったため、ソリューションは機能しました...とにかくありがとう
Mohsen Afshin

5
@MohsenAfshin同じ問題が発生しました--- XAMLで依存DLLを参照していました。ただし、ダミー変数を宣言する代わりに、XAMLで使用しているコンポーネントに名前を付けただけで、そのアセンブリをコピーするのに十分でした。
redcurry 2015年

5
@MikeKメインプロジェクト(実際には直接依存していません)に追加することは、さらに大きなハックであるimoです。次に、2つの場所で管理する必要があります(アップグレードまたは削除と同様に「管理」)。で、このハック、少なくとも、あなたが依存関係を削除すると、このハックを削除するように思い出させる素敵なコンパイル時のエラーを取得し、あなたはまだ一つだけの場所でそれを更新する必要があります。
jpmc26 2016

71

オーバーロードズルクの回答への単なる副注。

この方法でダミー参照を追加し、デバッグモードで機能しました。

public class DummyClass
{
    private static void Dummy()
    {
        var dummy = typeof(AbcDll.AnyClass);
    }
}

しかし、リリースモードでは、依存DLLはまだコピーされませんでした。
しかし、これはうまくいきました:

public class DummyClass
{
    private static void Dummy()
    {
        Action<Type> noop = _ => {};
        var dummy = typeof(AbcDll.AnyClass);
        noop(dummy);
    }
}

この情報は実際に把握するのに何時間もかかったので、私はそれを共有したいと思いました。


7
リリースモードでは、オプティマイザは「ダミー」が使用されていないと想定しているため、この行は不要であり、削除する必要があります。ただし、コードで「ダミー」を使用する場合、オプティマイザは不要であると想定しません。
Yucel、2016年

1
これは私には機能しません。AbcDll.AnyClassはまだ他のプロジェクトにコピーされていません
Matthew Lock

3
AbcDll.AnyClassパブリッククラスのパブリックフィールドまたはプロパティとして使用されていることを確認してください。このようなメソッド本体で使用すると、コンパイラはそれ認識しません。これは、このアセンブリの読み込みを遅らせるものであり、意図したものではありません。
John Leidegren、

52

はい、に設定Copy Localする必要がありますtrue。しかし、私はかなり確信しているあなたも参照する必要がありますアセンブリメイン・プロジェクト、およびセットからそれCopy Localまでtrueそれはちょうど依存アセンブリからコピーされません-だけでなく、。

Copy Local下のアセンブリをクリックしてReferencesF4キーを押すと、プロパティにアクセスできます。


2
@Brij、アセンブリは、必要なメインプロジェクトから参照されていますか?既に述べたように、そのプロジェクトからも参照する必要があると確信しています-依存アセンブリはそのようにコピーされません。その場合は、NuGetを使用するときに、すべての関連プロジェクトにアセンブリを追加する必要はありません。
Mike Perrenoud 2013

1
ここでの結論は何ですか?あなたには正しいようです-CopyLocalがtrueに設定されていても依存参照はコピーされません-その背後にあるロジックは何ですか?
mcmillab 2013

29
@mcmillab、つまりVisual Studioは他の依存プロジェクトからの依存関係を推測しません。プロジェクトAがプロジェクトBを参照する場合、プロジェクトAはプロジェクトBのすべての参照を持っている必要があります。すべてのプロジェクトBに.NETアセンブリが必要な場合は問題なく動作しますが、サードパーティアセンブリの場合は、両方のプロジェクトへの参照を追加する必要があります。
Mike Perrenoud 2013

12
@MichaelPerrenoudそれは本当だとは思いません。詳細なMSBuild出力を見ると、「2次およびn次の依存関係が含まれている」ことを示すResolveAssemblyReferenceの呼び出しが表示されます。これは、binフォルダーに表示される内容にも同意します(n番目の依存関係がコピーされます)。問題は、何がコピーされるかについて、いくつかの注意点があります。主にGACと間接参照です(参照の追加では不十分な場合があります)
Jack Ukleja

2
私の現在の経験では、これは「コピーされた」依存関係を除いて機能します。プロジェクトA.netは、外部C ++ dllを「常にコピー」するファイルとして参照します。プロジェクトB.netはプロジェクトAを参照します。ビルド時には、B / DebugにC ++ dllが含まれます。ただし、プロジェクトBを参照するアプリケーションXをビルドすると、C ++のdll がコピーされることあります(再ビルドを行った場合にのみ存在するようです)。
Benjol 2016

34

アセンブリ属性にすると滑らかに見えます

[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{        
    public ForceAssemblyReference(Type forcedType)
    {
        //not sure if these two lines are required since 
        //the type is passed to constructor as parameter, 
        //thus effectively being used
        Action<Type> noop = _ => { };
        noop(forcedType);
    }
}

使用法は次のとおりです。

[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]

ありがとうございますが、これは、AbcDll.AnyClassを既に参照している依存関係(プロジェクトX)にアセンブリ属性を追加したときにのみ機能します。そして、通常よりも多くのことは行わず、AbcDllを依存関係の出力ディレクトリにコピーします。それでも、メインの依存プロジェクトの出力にはコピーされません。また、AbcDllへの参照も追加しない限り、依存アセンブリに属性を追加できません。これを行うと、AbcDllは属性なしで既にコピーされています。
JS

25

この同じ問題に遭遇しました。背景情報:ビルドする前に、新しいProject Xをソリューションに追加しました。プロジェクトYはプロジェクトXに依存し、プロジェクトA、B、CはプロジェクトYに依存していました。

ビルドエラーは、プロジェクトA、B、C、Y、およびXのdllが見つからなかったことでした。

根本的な原因は、新しく作成されたProject Xが.NET 4.5をターゲットにし、残りのソリューションプロジェクトが.NET 4.5.1をターゲットにしたことです。 プロジェクトXはビルドされず、残りのプロジェクトもビルドされませんでした。

新しく追加されたプロジェクトが他のソリューションと同じ.NETバージョンをターゲットにしていることを確認してください。


1
参照プロジェクトは、古いバージョンの.NETである可能性があります。.NET 4.5用にビルドされたプロジェクトから.NET 4用にビルドされたプロジェクトを参照できます。
redcurry 2015年

18

これが役立つかどうかはわかりませんが、私にとっては、DLLを参照することがよくあります(もちろん、DLLをbinフォルダーに自動的に追加します)。ただし、そのDLLには追加のDLLが必要な場合があります(使用している関数によって異なります)。プロジェクトでそれらを参照したくないのは、実際に使用しているDLLと同じフォルダーに移動する必要があるだけだからです。

Visual Studioでは、「既存のファイルを追加する」ことでこれを実現しています。Add_dataフォルダー以外の場所に追加できるはずです。個人的にはルートに追加するだけです。

次に、そのファイルのプロパティを...に変更します。

ビルドアクション=なし(コンテンツのようなものに設定すると、実際には「ルート」バージョンがルートにコピーされ、さらにビンにコピーされます)。

出力フォルダーにコピー=新しい場合にコピー(基本的に、欠落している場合にのみBINフォルダーに入れますが、その後は行いません)

パブリッシュすると、追加したDLLはBINフォルダーにのみ存在し、パブリッシュの場所(他の場所)には存在しません。


10

また、探しているDLLがGACに含まれていないことを確認することもできます。Visual Studioは、ビルドマシンのGACにそれらのファイルが既に存在する場合、それらのファイルをコピーしないことについては賢明だと思います。

私は最近、GACにアセンブリが存在する必要があるSSISパッケージをテストしていたこの状況で実行しました。私はそれを忘れてしまったので、ビルド中にこれらのDLLが出ないのはなぜだろうと思っていました。

GACの内容を確認するには(Visual Studio開発者コマンドプロンプトから):

gacutil -l

または、読みやすくするためにファイルに出力します。

gacutil -l > output.txt
notepad.exe output.txt

アセンブリを削除するには:

gacutil -u MyProjectAssemblyName

また、GACからファイルを削除すると、ビルド後に\ binディレクトリにファイルが正しく出力されたことにも注意してください(ルートプロジェクトで直接参照されていないアセンブリについても)。これは、Visual Studio 2013 Update 5にありました。


ありがとう、そうです、MSBuildはGACでdllを見つけた場合、dllを出力フォルダーにコピーしません。
John-Philip

3

私の場合、私が同意しないTFS / VSのデフォルトの動作が原因で、それは最も愚かなことでした。

メインプロジェクトへの参照としてdllを追加することは機能しなかったため、「ローカルコピー=常に」を使用して、「既存のアイテム」として追加することにしました。それでもファイルはありませんでした。

ファイルがVSソリューションに存在し、すべてがローカルとサーバーの両方でコンパイルされていても、VS / TFSは実際にはファイルをソース管理に追加しなかったことがわかります。「保留中の変更」にはまったく含まれていません。ソースコントロールエクスプローラーに手動で移動し、[フォルダーにアイテムを追加]アイコンを明示的にクリックする必要がありました。

私はVSで15年間開発してきたので愚かです。私は以前これに遭遇しましたが、覚えていませんでしたが、ファイルが通常の参照であるためにすべてがコンパイルされたので、どういうわけか見逃しましたが、既存のアイテムとして追加されたファイルは、存在しないためコピーされていませんでしたソース管理サーバー。

私はこれで私の人生の2日間を失ったので、これが誰かの時間を節約することを願っています。


1
私はあなたに十分に感謝することはできません...あなたは私の時間をとても節約しました。これは私にとって解決策でした。また、根本的な問題も明らかになり、参照として追加したDLLはgitignoreパターンに一致したため、参照として追加した場合、プロジェクトに追加されませんでした。ファイルをソース管理に手動で追加する必要があります!!!
Mattkwish

2

これはnvirthの例を少し調整したものです

internal class DummyClass
{
    private static void Dummy()
    {
        Noop(typeof(AbcDll.AnyClass));
    }
    private static void Noop(Type _) { }
}

2

Postbuildイベントに追加して、必要なライブラリを出力ディレクトリにコピーします。XCopy pathtolibraries targetdirectoryのようなもの

プロジェクトのプロパティ->ビルドイベントで見つけることができます。


これは私にとってうまくいきました、そして私はこれがより良い答えだと思います。ダミー参照ソリューションは機能しますが、ハックですが、ビルド後のルールは同じ結果を達成するためのクリーンな方法です。
ケビンフィクター

2

問題:

ビルド出力に参照先DLLが含まれていないNuGetパッケージDLL(Newtonsoft.json.dll)でも同様の問題が発生しました。しかし、コンパイルはうまくいきます。

修正:

テキストエディタでプロジェクトを調べ、タグが含まれている参照を探します。TrueまたはFalseのように。「プライベート」は「ローカルコピー」の同義語です。アクションのどこかで、MSBuildは依存関係を特定します。依存関係を別の場所で見つけて、コピーしないことを決定しています。

したがって、各.csproj / .vbprojファイルを確認して、タグを手動で削除します。再構築すると、すべてがVisual StudioとMSBuildの両方で機能します。それが機能するようになったら、戻ってを必要な場所に更新できます。

参照:

https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/


1

コードでダミーを必要
としない:

実行可能プロジェクトへの参照を追加する

または実行可能プロジェクトの参照が(私の「フォールト」であった)に"Copy Local"設定されていることを確認します。TRUEこれは、参照されている基本ライブラリプロジェクトの設定を「上書き」したようです...


1

参照されているアセンブリを右クリックすると、[ ローカルコピー]というプロパティが表示されます。[ローカルコピー]がtrueに設定されている場合、アセンブリはビンに含まれている必要があります。ただし、Visual Studioには問題があるように見えますが、binフォルダーに参照先のdllが含まれていない場合があります...これは私にとって有効な回避策です:

ここに画像の説明を入力してください


1
Copy Loalが無効になり、これがstackoverflow.com/questions/15526491/…を
codemirror

1

TLDR; Visual Studio 2019は単に再起動が必要な場合があります。

Microsoft.NET.Sdkプロジェクトに基づくプロジェクトを使用してこの状況に遭遇しました。

<Project Sdk="Microsoft.NET.Sdk">

具体的には:

  • Project1:ターゲット .netstandard2.1
    • Microsoft.Extensions.Logging.ConsoleNugetによる参照
  • Project2:ターゲット .netstandard2.1
    • 参照Project1プロジェクト参照を経由して
  • Project2Tests:ターゲット .netcoreapp3.1
    • 参照Project2プロジェクト参照を経由して

テストの実行時に、Microsoft.Extensions.Logging.Console見つからなかったことを示すエラーメッセージが表示され、実際には出力ディレクトリにありませんでした。

私はをに追加Microsoft.Extensions.Logging.Consoleして問題を回避することにしました。ファイルに存在しているにもかかわらずProject2、Visual StudioのNuget ManagerがにMicrosoft.Extensions.Logging.Consoleインストールされているものとしてリストされていないことを発見しただけです。Project1Project1.csproj

Visual Studioをシャットダウンして再起動するだけで問題が解決され、余分な参照を追加する必要はありません。おそらくこれにより、45分の生産性の損失を節約できます:-)


実際、テストの途中でPC全体を再起動しましたが、問題なく動作しました
Noman_1

0

メインプロジェクトとProjectXのビルド出力パスの両方を同じフォルダーに設定すると、そのフォルダーに必要なすべてのdllを取得できます。


0

使用する依存dllに、プロジェクトのアプリケーションのターゲット.netフレームワークよりも高いターゲット.netフレームワークがないことを確認してください。

これを確認するには、プロジェクトを選択してALT + ENTERを押し、左側から[アプリケーション]を選択して、プロジェクトの[ターゲットフレームワーク]を選択します。

依存するdllターゲットフレームワーク= 4.0およびアプリケーションdllターゲットフレームワーク= 3.5の場合、これを4.0に変更します。

ありがとうございました!


0

上記の一般的なもの以外に、公開するマルチプロジェクトソリューションがありました。どうやらいくつかのファイルは異なるフレームワークをターゲットにしています。

だから私の解決策:プロパティ>特定のバージョン(False)


0

DLLを既存のアイテムとしてプロジェクトの1つに追加し、それをソートする必要があります


0

VS2019 V16.6.3

私にとっての問題は、どういうわけか、DLLが親プロジェクトのbinフォルダーにコピーされていないプロジェクトのメイン.projファイルが次のようなエントリになってしまったことです。

<ProjectReference Include="Project B.csproj">
  <Project>{blah blah}</Project>
  <Name>Project B</Name>
  <Private>True</Private>
</ProjectReference>

手動で行を削除しました <Private>True</Private>し、メインプロジェクトのビルドごとにDLLをメインプロジェクトのbinフォルダーにコピーしました。

メインプロジェクトの参照フォルダーにある問題のプロジェクトの参照に移動し、それをクリックしてプロパティを表示すると、「ローカルにコピー」設定があります。プライベートタグはこの設定に相当しますが、私にとっては、何らかの理由でコピーローカルを変更しても、.projファイルのプライベートタグには影響がありませんでした。

不愉快なことに、私は参照のコピーローカル値を変更しませんでした。それがどのように設定されたかわからず、VSの愚かな問題を追跡するのにもう1日無駄になりました。

原因を突き止めるのに役立つ他のすべての回答に感謝します。

HTH

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.