MSB3247の解決-同じ依存アセンブリの異なるバージョン間で競合が見つかりました


427

.NET 3.5ソリューションは、msbuildでコンパイルすると、この警告で終了しました。

NDependが役立つ場合がありますが、この場合、それ以上の詳細は提供されませんでした。ボブ同様に、依存アセンブリの古いバージョンを参照しているアセンブリが見つかるまで、ILDASMで各アセンブリを開く必要がありました。

私はVS 2010 Beta 2からMSBUILDを使用しようとしました(Connectの記事で、これはCLRの次のバージョンで修正されたと示されています)が、それ以上の詳細情報は提供されていません(Beta 2以降で修正された可能性があります)。

より良い(より自動化された)アプローチはありますか?


2
私の場合、ソリューション内のすべてのプロジェクトが同じバージョンのnugetパッケージを実行していることを確認する必要がありました(すべてを最新に更新できます)。
マイケル

回答:


576

「MSBuildプロジェクトビルド出力の詳細度」を「詳細」以上に変更します。これを行うには、次の手順に従います。

  1. [オプション]ダイアログを表示します([ ツール ] -> [オプション...])。
  2. 左側のツリーで、プロジェクトとソリューションを選択しますノードを選択し、[ Build and Run]を選択します
    • 注:このノードが表示されない場合は、ダイアログの下部にある[ すべての設定を表示]チェックボックスがオンになっていることを確認してください。
  3. 表示されるツール/オプションページで、MSBuildプロジェクトのビルド出力の詳細レベルを、バージョンに応じて適切な設定に設定します。

  4. プロジェクトをビルドし、出力ウィンドウを確認します。

MSBuildメッセージを確認してください。ResolveAssemblyReferencesMSB3247発信タスクであるタスクは、あなたがこの特定の問題をデバッグする必要があります。

私の特定のケースは、SqlServerCeへの誤った参照でした。下記参照。2つの異なるバージョンのSqlServerCeを参照する2つのプロジェクトがありました。古いバージョンのプロジェクトに行って、参照を削除し、正しい参照を追加しました。

Target ResolveAssemblyReferences:
    Consider app.config remapping of assembly "System.Data.SqlServerCe, ..." 
        from Version "3.5.1.0" [H:\...\Debug\System.Data.SqlServerCe.dll] 
        to Version "9.0.242.0" [C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PublicAssemblies\System.Data.SqlServerCe.dll]
        to solve conflict and get rid of warning.
    C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets : 
        warning MSB3247: Found conflicts between different versions of the same dependent assembly.

参照されているアセンブリのバージョンを確認するために、各アセンブリを開く必要はありません。

  • 各リファレンスのプロパティを確認できます。
  • プロジェクトのプロパティを開き、参照セクションのバージョンを確認します。
  • テキストエディタでプロジェクトを開きます。
  • .Net Reflectorを使用します。

5
あなたのソリューションは私には良さそうですが、バージョン番号を表示するために参照セクションを使用することが常に役立つとは思いません。使用しているバージョンと.csprojファイルに実際に記載されているバージョンの違いについて、VSが "嘘をつく"ことをよく目にしました。
David Gardiner、

5
@David Gardiner-C#プロジェクトを使用する際の「嘘」の記述に同意します。私の経験では、C#プロジェクトは、参照されたバージョンとコンパイル/リンクされた実際のバージョンに関して混乱する可能性があります。これが発生した場合は、ソリューションをクリーンアップし、binおよびobjフォルダーを手動で削除してから、%APPDATA%の一時プロジェクトアセンブリを削除します。再構築ソリューションは通常、問題を解決します。(VBがこの特定の問題に悩まされることはめったにありません。)
AMissico 2010

54
実際に出力ウィンドウを使用するように指示することで勝利します。ビルドは、F5 +エラーリストウィンドウよりもはるかに多くなります。
JJS 2010

2
ErikHeemskerkが彼の回答で述べたように、Visual Studio 2010では、ResolveAssemblyReferencesの出力を表示するために出力の詳細度を詳細に設定する必要があります。
Robin Clowers

12
ヒント:詳細なビルド出力で正確な場所を見つけるには、テキストをテキストエディターにコピーし、「同じ依存アセンブリの異なるバージョン間で競合が見つかりました。」を検索します。
Contango、2011

133

Mike HadlowがAsmSpy呼ばれる小さなコンソールアプリを投稿しました。これは、各アセンブリの参照をかなりうまくリストします。

Reference: System.Net.Http.Formatting
        4.0.0.0 by Shared.MessageStack
        4.0.0.0 by System.Web.Http

Reference: System.Net.Http
        2.0.0.0 by Shared.MessageStack
        2.0.0.0 by System.Net.Http.Formatting
        4.0.0.0 by System.Net.Http.WebRequest
        2.0.0.0 by System.Web.Http.Common
        2.0.0.0 by System.Web.Http
        2.0.0.0 by System.Web.Http.WebHost

これは、MSBuild出力に依存するよりも、警告MSB3247の一番下に到達するためのはるかに速い方法です。


1
AsmSpyは素晴らしいです。バージョンが一致しないサードパーティのDLLへの参照を探していることを覚えておく必要があります。一般に、標準ライブラリへの参照のバージョンが一致しない場合、これらの警告は発生しません(そして、それらがたくさん表示されます)。
Tod Thomson

これは、問題をすぐに解決するのに役立つすばらしい小さなツールです。ただし、私の場合は、サードパーティのDLLではなく、mscorlib.dllへの異なる参照を持つSystem.Management.Automation.dllへの参照です。
Chris Gillum、2012

このツールは便利ですが、すべての状況で機能するわけではありません。少なくとも.NET 4.5プロジェクトの場合、衝突する参照バージョンは表示されませんでした。+ msbuildの出力では、問題のDLLにパスとすべての名前が付けられます。
10:09

11
みんな、親切な言葉をありがとう:)
マイク・ハドロー2013年

あなたは私に数時間の仕事を救ってくれました!詳細な出力に目を通すことは役に立ちましたが、一度実行すると、ツールで再度確認するのは簡単でした。
Norman H

22

@AMissicoの回答では不十分な場合があります。私の場合、出力ウィンドウでエラーを見つけることができなかったため、次の手順を実行して、ログファイルを作成して分析することにしました。

  1. ビルドログをファイルに保存しています... https://msdn.microsoft.com/en-us/library/ms171470.aspx

    msbuild MyProject.proj /fl /flp:logfile=MyProjectOutput.log;verbosity=detailed

  2. テキスト:warning MS...または特定の警告情報(例:9293行)Found conflicts between different versions...を見つけます。競合エラーの詳細は、このメッセージの上に表示されます(例:9277行)There was a conflicts between... エラーメッセージを見つける

Visual Studio 2013


出力で3277を検索するための素晴らしいヒント。
sfuqua

21

(少なくともVisual Studio 2010では)問題を特定するには、出力の詳細度を少なくとも[詳細]に設定する必要があることがわかりました。

私の問題は以前はGAC参照であった参照だったのかもしれませんが、私のマシンを再インストールした後はもはやそうではありませんでした。


1
「ツール」->「オプション」->「プロジェクトとソリューション」->「ビルドして実行」に移動して、出力の詳細度を設定します。
Farshid 2018年

8

私は同じエラーがあり、他の答えでそれを理解することができませんでした。NuGetパッケージを「統合」できることがわかりました。

  1. ソリューションを右クリック
  2. [Nugetパッケージの管理]をクリックします
  3. タブを統合し、同じバージョンに更新します。

7

デフォルトのASP.NET MVC 4ベータに対して生成されたこの警告は、 こちらをご覧ください

で、この警告はプロジェクトの.csprojファイルを手動で編集することで解消できます。

変更........:リファレンスInclude = "System.Net.Http"

読み方......:Reference Include = "System.Net.Http、Version = 4.0.0.0"


1
私はこれに従いました、そしてエラーは消えました。それでも方法や理由がわからないので、VS2010でMVC 4プロジェクトを開始し、VS2012に移行しました。ただし、バージョン属性を追加すると、エラーが消えました。ありがとう
MaiOM

6

依存関係リーダーを使用する

dep.exeを使用すると、フォルダー全体のネストされた依存関係をすべて一覧表示できます。grepやawkなどのUNIXツールと組み合わせると、問題の解決に役立ちます

複数のバージョンで参照されているアセンブリを見つける

$ dep | awk '{ print $1 " " $2; print $4 " " $5 }' | awk '{ if (length(versions[$1]) == 0) versions[$1] = $2; if (versions[$1] != $2) errors[$1] = $1; }  END{ for(e in errors) print e } ' 
System.Web.Http            

このあいまいなコマンドラインはdep.exeを実行し、出力を2回パイプしてawkに送信します。

  • 親と子を単一の列に配置します(デフォルトでは、各行には1つの親と子が含まれ、この親がその子に依存しているという事実を表現します)
  • 次に、連想配列を使用して一種の「グループ化」を行います

このアセンブリがビンにどのように取り込まれたかを理解する

$ dep myproject/bin | grep -i System\.Web\.Http
MyProject-1.0.0.0 >> System.Web.Http.Web-5.2.3.0 2 ( FooLib-1.0.0.0 )
MyProject-1.0.0.0 >> System.Web.Http.Web-4.0.0.0 2 ( BarLib-1.0.0.0 )
FooLib-1.0.0.0 > System.Web.Http.Web-5.2.3.0 1
BarLib-1.0.0.0 > System.Web.Http.Web-4.0.0.0 1 

この例では、ツールはSystem.Web.Http 5.2.3がFooLibへの依存関係に由来するのに対し、バージョン4.0.0はBarLibに由来することを示します。

次に、あなたは

  • ライブラリの所有者に同じバージョンを使用するように説得する
  • それらの1つを使用するのをやめる
  • 最新バージョンを使用するように構成ファイルにバインディングリダイレクトを追加する

これらをWindowsで実行する方法

UNIXタイプのシェルがない場合は、awkとを実行する前にダウンロードする必要がありますgrep。次のいずれかを試してください


4

私もこの問題を抱えており、AMissicoのアドバイスを使用して問題を発見しました(詳細レベルを詳細に設定する必要がありましたが)。

問題は犯人を見つけた後でも、実際には非常に簡単でした。

背景:プロジェクトをVS2008からVS2010にアップグレードしました。VS2008では、ターゲットフレームワークは3.5でしたが、VS2010に導入したときに、4(フル)に切り替えました。Crystalレポートを含むいくつかのサードパーティコンポーネントもアップグレードしました。

ほとんどのシステム参照はバージョン4.0.0.0を指していることが判明しましたが、いくつかは自動的に変更されておらず(SystemおよびSystem.Web.Services)、2.0.0.0をまだ見ていました。Crystalレポートは4.0.0.0を参照しているため、ここで競合が発生していました。ソリューションエクスプローラーの最初のシステムライブラリにカーソルを置き、リストを下にカーソルを移動して2.0.0.0への参照を探し、新しい4.0.0.0バージョンを削除して再度追加するだけでうまくいきました。

奇妙なことに、ほとんどの参照が正しく更新されていて、Crystalレポート用でなければ、おそらく気付かなかったでしょう...



2

ここで述べように、未使用の参照を削除する必要があり、警告が表示されます。


1

ASP.NETビルドマネージャーは、フォルダーをアルファベット順に移動してWebサイトを構築します。各フォルダーについて、依存関係を把握し、最初に依存関係を構築してから、選択したフォルダーを構築します。

この場合、〜/ Controlsである問題のあるフォルダーが最初にビルドされるように選択されていますが、未知の理由により、他のコントロールと同じアセンブリ内ではなく、別のアセンブリとしていくつかのコントロールをビルドします(ようです)一部のコントロールが同じフォルダー内の他のコントロールに依存しているという事実に関連している)。

次に、ビルドされる次のフォルダー(〜/ File-Center / Control)は、〜/ Controlsに依存するルートフォルダー〜/に依存しているため、フォルダー〜/ Controlsは、分離されたコントロールのみが再度ビルドされます独自のアセンブリに、他のコントロールと同じアセンブリに結合され、分離されたアセンブリは引き続き参照されます。

したがって、この時点で2つのアセンブリには(少なくとも)同じコントロールがあり、ビルドは失敗します。

なぜこれが起こったのかはまだわかりませんが、Controlsフォルダー名をZControlsに変更することで回避できました。この方法では、〜/ File-Center / Controlの前にビルドされず、ビルドされた後にのみこの方法でビルドされますそれがあるべきように。


1

クイックフィックス:

ソリューションを右クリック->ソリューションのNuGetパッケージを管理-> [ 統合]で、同じパッケージの異なるバージョンがインストールされているかどうかを確認できます。異なるバージョンをアンインストールし、最新のものをインストールします。


1

場合によってAutoGenerateBindingRedirectsは(を使用してもGenerateBindingRedirectsOutputType)十分ではありません。すべてのThere was a conflictエントリを検索して1つずつ手動で修正するのは面倒な場合があるため、ログ出力を解析して生成する小さなコードを書きました(ダンプ先:) stdout

// Paste all "there was a conflict" lines from the msbuild diagnostics log to the file below
const string conflictFile = @"C:\AssemblyConflicts.txt";

var sb = new StringBuilder();
var conflictLines = await File.ReadAllLinesAsync(conflictFile);
foreach (var line in conflictLines.Where(l => !String.IsNullOrWhiteSpace(l)))
{
    Console.WriteLine("Processing line: {0}", line);

    var lineComponents = line.Split('"');
    if (lineComponents.Length < 2) 
        throw new FormatException("Unexpected conflict line component count");

    var assemblySegment = lineComponents[1];
    Console.WriteLine("Processing assembly segment: {0}", assemblySegment);
    var assemblyComponents = assemblySegment
                              .Split(",")
                              .Select(kv => kv.Trim())
                              .Select(kv => kv.Split("=")
                              .Last())
                              .ToArray();

    if (assemblyComponents.Length != 4) 
        throw new FormatException("Unexpected conflict segment component count");

    var assembly = assemblyComponents[0];
    var version = assemblyComponents[1];
    var culture = assemblyComponents[2];
    var publicKeyToken = assemblyComponents[3];

    Console.WriteLine("Generating assebmly redirect for Assembly={0}, Version={1}, Culture={2}, PublicKeyToken={3}", assembly, version, culture, publicKeyToken);
    sb.AppendLine($"<dependentAssembly><assemblyIdentity name=\"{assembly}\" publicKeyToken=\"{publicKeyToken}\" culture=\"{culture}\" /><bindingRedirect oldVersion=\"0.0.0.0-{version}\" newVersion=\"{version}\" /></dependentAssembly>");
}

Console.WriteLine("Generated assembly redirects:");
Console.WriteLine(sb);

ヒント:MSBuild BinaryとStructured Log Viewerを使用して、警告を発するプロジェクト内の競合のバインディングリダイレクトのみを生成します(つまり、there was a conflict上記のコードの入力テキストファイルへのこれらの行を過ぎて[ AssemblyConflicts.txt])。


0

(内部)依存関係を考慮に入れずに行う最も簡単な方法:

  1. 「ソリューションエクスプローラー」を開きます。
  2. 「すべてのファイルを表示」をクリックします
  3. 「参照」を展開します
  4. 1つ(または複数)の参照が、残りのアイコンとわずかに異なるアイコンで表示されます。通常、黄色いボックスが付いているので、メモを取ることを勧めています。削除するだけです。
  5. 参照を追加して、コードをコンパイルします。
  6. それで全部です。

私の場合、MySQL参照に問題がありました。どういうわけか、利用可能なすべての参照のリストの下に、その3つのバージョンをリストすることができます。上記のプロセス1から6を実行したところ、うまくいきました。


0

Visual Studio for Macコミュニティの追加:

以下のようAMissicoの答えは、ログレベルを変更する必要があり、かつASMSpyもASMSpyPlusどちらもクロスプラットフォームソリューションとして使用できますが、ここではMac用のVisual Studioの短い加算は次のとおりです。

https://docs.microsoft.com/en-us/visualstudio/mac/compiling-and-building

それは中だVisual Studioのコミュニティ →設定...→プロジェクト→ビルドログ→冗長性


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