MSB3247 해결-동일한 종속 어셈블리의 다른 버전간에 충돌이 발견되었습니다.


427

.NET 3.5 솔루션은 msbuild로 컴파일 할 때이 경고로 끝났습니다.

때로는 NDepend가 도움이 될 수 있지만이 경우 자세한 내용은 제공하지 않았습니다. Bob과 마찬가지로 이전 버전의 종속 어셈블리를 참조하는 어셈블리를 찾을 때까지 ILDASM에서 각 어셈블리를 여는 데 의존했습니다.

VS 2010 Beta 2에서 MSBUILD를 사용해 보았습니다 (Connect 기사에서 이것이 CLR의 다음 버전에서 수정되었다고 표시했지만).

더 나은 (보다 자동화 된) 접근 방식이 있습니까?


2
필자의 경우 솔루션의 모든 프로젝트가 동일한 버전의 너겟 패키지를 실행하고 있는지 확인해야했습니다 (모든 것을 최신으로 업데이트 할 수 있음).
Michael

답변:


576

"MSBuild 프로젝트 빌드 출력 상세"를 "상세"이상으로 변경하십시오. 이렇게하려면 다음 단계를 수행하십시오.

  1. 옵션 대화 상자를 엽니 다 ( 도구-> 옵션 ... ).
  2. 왼쪽 트리에서 프로젝트 및 솔루션 노드를 선택한 다음 빌드 및 실행 을 선택 하십시오 .
    • 참고 :이 노드가 표시되지 않으면 모든 설정 표시 대화 상자 하단의 확인란이 선택되어 있는지 확인하십시오 .
  3. 도구 / 옵션 페이지가 나타나면 버전에 따라 MSBuild 프로젝트 빌드 출력 상세 레벨을 적절한 설정으로 설정하십시오.

  4. 프로젝트를 빌드하고 출력 창을보십시오.

MSBuild 메시지를 확인하십시오. ResolveAssemblyReferencesMSB3247 유래, 당신이 특정 문제를 디버깅하는 데 도움이되어야하는 작업입니다 작업.

내 특정 사례는 SqlServerCe에 대한 잘못된 참조였습니다. 아래를 참조하십시오. 두 가지 버전의 SqlServerCe를 참조하는 두 개의 프로젝트가 있습니다. 이전 버전의 프로젝트로 이동하여 참조를 제거한 다음 올바른 참조를 추가했습니다.

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 리플렉터를 사용하십시오.

5
귀하의 솔루션은 나에게 잘 어울리지 만 참조 번호 섹션을 사용하여 버전 번호를 보는 것이 항상 유용하다고 생각하지 않습니다. 나는 종종 어떤 버전이 .csproj 파일에 언급되어 있는지 vs.
David Gardiner

5
@David Gardiner-C # 프로젝트를 사용할 때 "거짓말"에 동의합니다. 내 경험상 C # 프로젝트는 참조 버전과 컴파일 / 링크 된 실제 버전과 관련하여 혼동 될 수 있습니다. 이 경우 솔루션을 정리하고 bin 및 obj 폴더를 수동으로 삭제 한 다음 % APPDATA %에서 임시 프로젝트 어셈블리를 삭제하십시오. 재 구축 솔루션은 일반적으로 문제를 해결합니다. (VB는이 특정한 문제로 거의 고통
받지 않습니다

54
사람들에게 실제로 출력 창을 사용하라고 알려주십시오. 빌드는 F5 + Error List 창 이상입니다.
JJS

2
ErikHeemskerk가 그의 답변에서 언급했듯이 Visual Studio 2010에서는 ResolveAssemblyReferences의 출력을 보려면 출력 세부 정보를 자세하게 설정해야합니다.
Robin Clowers

12
힌트 : 자세한 빌드 출력에서 ​​정확한 지점을 찾으려면 텍스트를 텍스트 편집기로 복사하고 "동일한 종속 어셈블리의 다른 버전간에 충돌이 발견되었습니다"를 검색하십시오.
Contango

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

이 도구는 훌륭하지만 모든 상황에서 작동하지는 않습니다. 적어도 .NET 4.5 프로젝트의 경우 충돌 참조 버전이 표시되지 않았습니다. + msbuild 출력은 해당 DLL의 이름을 경로와 모두로 지정합니다.
twomm

11
친절한 단어들 주셔서 감사합니다 :)
Mike Hadlow

당신은 나에게 몇 시간의 작업을 저장했습니다! 자세한 출력을 읽는 데 도움이되었지만 일단 수행하면 도구로 다시 쉽게 확인할 수 있습니다.
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

8

나는 같은 오류가 있었고 다른 대답으로 알아낼 수 없었습니다. NuGet 패키지를 "통합"할 수 있다는 것을 알았습니다.

  1. 솔루션을 마우스 오른쪽 버튼으로 클릭하십시오
  2. Nuget 패키지 관리를 클릭하십시오.
  3. 탭을 통합하고 동일한 버전으로 업데이트하십시오.

7

기본 ASP.NET MVC 4 베타에 대해 생성 된이 경고는 여기를 참조하십시오.

프로젝트의 .csproj 파일을 수동으로 편집하여이 경고를 제거 할 수 있습니다.

modify ........ : 참조 Include = "System.Net.Http"

읽을 내용 : 참조 Include = "System.Net.Http, Version = 4.0.0.0"


1
나는 이것을 따랐고 오류는 사라졌다. 여전히 어떻게 또는 왜인지 모르겠지만 VS2010으로 MVC 4 프로젝트를 시작한 다음 VS2012에서 마이그레이션했습니다. 그러나 버전 속성을 추가하면 오류가 사라졌습니다. 감사합니다
MaiOM

6

의존성 리더 사용

dep.exe 를 사용 하면 전체 폴더의 모든 중첩 된 종속성을 나열 할 수 있습니다. grep 또는 awk와 같은 유닉스 도구와 결합하면 문제를 해결하는 데 도움이 될 수 있습니다

둘 이상의 버전에서 참조되는 어셈블리 찾기

$ 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를 실행 한 다음 출력을 두 번 awk

  • 부모와 자식을 단일 열에 넣습니다 (기본적으로 각 줄에는 부모와 자식이 포함되어있어이 부모가 해당 자식에 의존한다는 사실을 나타냅니다)
  • 그런 다음 연관 배열을 사용하여 일종의 '그룹화'를 수행하십시오.

이 어셈블리를 휴지통에서 가져 오는 방법 이해

$ 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에서 제공됨을 보여줍니다.

그런 다음 사이에서 선택할 수 있습니다

  • 라이브러리 소유자에게 동일한 버전을 사용하도록 설득
  • 그들 중 하나를 사용 중지
  • 최신 버전을 사용하도록 구성 파일에 바인딩 리디렉션 추가

Windows에서 이러한 작업을 실행하는 방법

유닉스 타입 쉘이 없다면 awkand 를 실행하기 전에 하나를 다운로드해야한다 grep. 다음 중 하나를 시도하십시오


4

나도이 문제가 있었고 AMissico의 조언을 사용하여 문제를 발견했습니다 (자세한 수준을 세부로 설정해야했지만).

범인을 찾은 후에도 문제는 실제로 매우 간단했습니다.

배경 : 프로젝트를 VS2008에서 VS2010으로 업그레이드했습니다. VS2008에서 대상 프레임 워크는 3.5 였고 VS2010으로 가져올 때 4 (Full)로 전환했습니다. 또한 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 빌드 관리자는 폴더를 알파벳 순으로 살펴보면서 웹 사이트를 구축하고 있으며 각 폴더마다 종속성을 파악한 다음 선택한 폴더를 종속성으로 작성합니다.

이 경우 ~ / Controls 인 문제가있는 폴더는 처음에 빌드되도록 선택되었지만 아직 알 수없는 이유로 다른 컨트롤과 동일한 어셈블리 내부가 아닌 별도의 어셈블리로 일부 컨트롤을 빌드합니다 ( 일부 컨트롤은 동일한 폴더의 다른 컨트롤에 종속된다는 사실에 연결되어야합니다.

그런 다음 빌드되는 다음 폴더 (~ / File-Center / Control)는 ~ / Controls에 종속 된 루트 폴더 ~ /에 종속되므로 ~ / Controls 폴더는 이번에 만 분리 된 컨트롤 만 다시 빌드됩니다. 분리 된 어셈블리가 여전히 참조되는 다른 컨트롤과 동일한 어셈블리에 자체 어셈블리에 연결됩니다.

따라서이 시점에서 2 어셈블리 (적어도)는 동일한 컨트롤을 가지며 빌드가 실패합니다.

우리는 왜 이런 일이 일어 났는지 알지 못하지만 Controls 폴더 이름을 ZControls로 변경하여 해결할 수있었습니다. 그것은해야합니다.


1

빠른 수정:

솔루션-> 솔루션의 NuGet 패키지 관리-> 통합 아래 에서 동일한 패키지의 다른 버전이 설치되어 있는지 확인할 수 있습니다. 다른 버전을 제거하고 최신 버전을 설치하십시오.


1

때로는 AutoGenerateBindingRedirects충분하지 않습니다 (조차도 GenerateBindingRedirectsOutputType). 모든 There was a conflict항목을 검색 하고 하나씩 수동으로 수정하는 것은 지루할 수 있으므로 로그 출력을 구문 분석하고 생성하는 작은 코드를 작성했습니다 (덤프 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. 나머지 아이콘과 약간 다른 아이콘을 가진 하나 이상의 참조가 표시됩니다. 일반적으로 메모를 할 것을 제안하는 노란색 상자가 있습니다. 그냥 제거하십시오.
  5. 참조를 다시 추가하고 코드를 컴파일하십시오.
  6. 그게 다야.

필자의 경우 MySQL 참조에 문제가있었습니다. 어떻게 든 사용 가능한 모든 참조 목록 아래에 세 가지 버전을 나열 할 수 있습니다. 위의 1 ~ 6 단계를 따르고 나에게 도움이되었습니다.


0

Mac 용 Visual Studio 커뮤니티 추가 :

같이 AMissico의 대답은 로그 수준을 변경해야하고, ASMSpy도 ASMSpyPlus도는 크로스 플랫폼 솔루션으로 사용할 수 있으며, 여기에 Mac 용 비주얼 스튜디오에 대한 간단한 추가 항목입니다 :

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

이 글은 다음의 비주얼 스튜디오 커뮤니티 환경 설정 → ... → 프로젝트 → 빌드 로그인 → 상세


0

다시 선명하게하는 경우 솔루션에서 사용되지 않은 모든 참조를 제거하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.