programing

MSB3247 해결 - 동일한 종속 어셈블리의 서로 다른 버전 간에 충돌이 발견됨

powerit 2023. 5. 13. 11:04
반응형

MSB3247 해결 - 동일한 종속 어셈블리의 서로 다른 버전 간에 충돌이 발견됨

.NET 3.5 솔루션은 msbuild로 컴파일할 때 이 경고가 발생했습니다.

때때로 NDepend가 도움이 될 수도 있지만 이 경우에는 더 이상의 세부 사항을 제공하지 않았습니다.처럼 저는 의존적인 어셈블리의 오래된 버전을 참조하는 어셈블리를 찾을 때까지 ILDASM의 각 어셈블리를 여는 데 의지해야 했습니다.

VS 2010 베타 2의 MSBUILD를 사용해 보았지만(연결 기사에서 CLR의 다음 버전에서 수정되었음을 나타냄), 그것도 더 이상의 세부 사항을 제공하지 않았습니다(베타 2 이후 수정될 수 있음).

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

MS Build project build 출력 상세도를 "상세" 이상으로 변경합니다.이 작업을 수행하려면 다음 단계를 수행합니다.

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

    • VS2012, VS2013 또는 VS2015의 경우 진단(이러한 버전의 메시지에는 "상세"를 사용해야 한다고 표시되지만, 이는 명백한 오류입니다. "진단"을 사용해야 합니다.)
    • VS2010에 참여할 때 자세히 설명
    • VS2008 또는 이전 버전에서는 정상으로 충분합니다.
  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 Reflector를 사용합니다.

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 경고의 진상을 파악하는 훨씬 빠른 방법입니다.

때때로 @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...은 이 .There was a conflicts between... 오류 메시지 찾기

비주얼 스튜디오 2013

Visual Studio 2010에서는 문제를 발견하려면 출력 상세도를 Detailed 이상으로 설정해야 합니다.

제 문제는 이전에 GAC 참조였던 참조일 수도 있지만, 기계를 다시 설치한 후에는 더 이상 그렇지 않았습니다.

저도 같은 오류가 있어서 다른 답변으로는 이해할 수 없었습니다.NuGet 패키지를 "통합"할 수 있다는 것을 알게 되었습니다.

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

이 경고는 기본 ASP에 대해 생성되었습니다.NET MVC 4 베타 여기 참조

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

modify........: 참조 포함="시스템.넷.Http"

…을 읽으려면 ....: 참조에는 =가 포함됩니다."시스템.넷.Http, 버전=4.0.0.0"

종속성 판독기 사용

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

이 예에서 도구는 해당 시스템을 표시합니다.Web.Http 5.2.3은 FooLib에 대한 종속성에서 온 반면 버전 4.0.0은 BarLib에서 온 것입니다.

그럼 둘 중 하나를 선택할 수 있습니다.

  • 립의 소유자들이 같은 버전을 사용하도록 설득하기
  • 사용을 중지합니다.
  • 최신 버전을 사용하기 위해 구성 파일에 바인딩 리디렉션 추가

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

type 이 없는 type shell을 할 수 awk그리고.grep 중 를 시도해 .

저도 이 문제가 있었고 문제를 발견하기 위해 아미시코의 조언을 사용했습니다(장황도 수준을 Detailed로 설정해야 했지만).

범인을 찾은 후에 문제는 사실 꽤나 직접적이었습니다.

배경:프로젝트를 VS2008에서 VS2010으로 업그레이드했습니다.VS2008에서 목표 프레임워크는 3.5였으며 VS2010으로 가져왔을 때 4(전체)로 전환했습니다.Crystal 보고서를 포함한 일부 타사 구성 요소도 업그레이드했습니다.

버전 4.0.0.0을 가리키는 대부분의 시스템 참조가 자동으로 변경되지 않았습니다(시스템 및 시스템).2.0.0.0을 계속 보고 있었습니다.Crystal 보고서는 4.0.0.0을 참조하고 있으므로 여기서 충돌이 발생했습니다.솔루션 탐색기의 첫 번째 시스템 라이브러리에 커서를 놓고 목록 아래로 커서를 이동하여 2.0.0.0에 대한 참조를 찾기만 하면 새로운 4.0.0 버전을 제거하고 다시 추가할 수 있습니다.

이상한 것은 대부분의 참조가 정확하게 업데이트되었다는 것입니다. 그리고 크리스탈 보고서가 아니었다면 아마 전혀 눈치채지 못했을 것입니다.

빠른 수정:

솔루션을 마우스 오른쪽 버튼으로 클릭 -> 솔루션용 NuGet 패키지 관리 -> 통합에서 동일한 패키지의 다른 버전이 설치되었는지 확인할 수 있습니다.다른 버전을 제거하고 최신 버전을 설치합니다.

Mike Hadlow 애플리케이션을 기반으로 애플리케이션을 만들었습니다. AsmsSpy.

내 앱은 GUI가 포함된 WPF 앱이며 홈 웹 서버인 AsmSpyPlus.exe에서 다운로드할 수 있습니다.

코드는 GitHub에서 사용할 수

Gui 샘플

여기에서 언급한 것처럼 사용되지 않는 참조를 제거해야 합니다. 그러면 경고가 표시됩니다.

ASP.NET 빌드 관리자는 폴더를 알파벳 순으로 살펴봄으로써 웹 사이트를 구축하고 있으며, 각 폴더에 대해 종속성을 파악하여 종속성을 먼저 구축한 다음 선택한 폴더를 구축합니다.

이 경우 문제가 되는 폴더인 ~/Controls가 처음에 빌드되도록 선택되는데, 아직 알 수 없는 이유로 인해 일부 컨트롤이 다른 컨트롤과 동일한 어셈블리 내부가 아닌 별도의 어셈블리로 빌드됩니다(일부 컨트롤이 동일한 폴더의 다른 컨트롤에 종속되어 있다는 사실과 연결된 것으로 보입니다).

그런 다음 빌드된 다음 폴더(~/File-Center/Control)는 ~/Controls에 종속된 루트 폴더에 종속됩니다.따라서 폴더 ~/Controls는 자신의 어셈블리로 분리되었던 컨트롤이 이제 다른 컨트롤과 동일한 어셈블리에 결합되고 분리된 어셈블리는 여전히 참조되고 있습니다.

따라서 이 시점에서 2개의 어셈블리(최소한)에 동일한 컨트롤이 있고 빌드가 실패합니다.

이 문제가 발생한 이유는 아직 알 수 없지만 Controls 폴더 이름을 ZControls로 변경하여 해결할 수 있었습니다. 이 방법은 ~/File-Center/Control 이전에는 빌드되지 않으며, 이후에는 빌드되지 않고 원래대로 빌드됩니다.

은 씩끔가.AutoGenerateBindingRedirects를 사용해도 충분하지 않습니다.모든 것을 검색하는 중There was a conflict을 입력하고 은 지루할 수 투 항목하입덤수수동정것로로하는출그로력구을은다문분니생작조습했성코작을석프하각여성드하는을은나루므으지력씩할으있수하고덤▁that▁entriesd▁a▁and).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 conflictAssemblyConflicts.txt]).

(내부) 종속성을 고려하지 않는 간단한 방법:

  1. 솔루션 탐색기를 엽니다.
  2. 모든 파일 표시를 클릭합니다.
  3. "참조"를 펼치기
  4. 나머지 아이콘과 약간 다른 하나 이상의 참조가 표시됩니다.일반적으로 노란색 상자가 표시되어 있어 메모할 것을 권장합니다.그것을 제거하세요.
  5. 참조를 다시 추가하고 코드를 컴파일합니다.
  6. 이상입니다.

저의 경우 MySQL 참조에 문제가 있었습니다.어떻게든, 저는 이용 가능한 모든 참고 자료 목록 아래에 그것의 세 가지 버전을 나열할 수 있었습니다.위의 1번부터 6번까지의 과정을 따랐고 저에게는 효과가 있었습니다.

Mac 커뮤니티용 Visual Studio 추가:

Amissico의 답변에는 로그 수준을 변경해야 하며 ASMSpy 또는 ASMSpyPlus는 크로스 플랫폼 솔루션으로 제공되지 않으므로 다음은 Mac용 Visual Studio에 대한 간단한 추가 사항입니다.

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

Visual Studio Community → 기본 설정...프로젝트 → 로그 작성 → 장황성

리샤퍼가 있는 경우 솔루션에서 사용되지 않는 참조를 모두 제거합니다.

언급URL : https://stackoverflow.com/questions/1871073/resolving-msb3247-found-conflicts-between-different-versions-of-the-same-depen

반응형