Resolvendo MSB3247 - Encontrados conflitos entre diferentes versões de um mesmo conjunto dependente

StackOverflow https://stackoverflow.com/questions/1871073

  •  18-09-2019
  •  | 
  •  

Pergunta

A NET 3.5 solução acabou com este aviso ao compilar com msbuild.

Às vezes NDepend pode ajudar, mas, neste caso, não deu mais detalhes. Como Bob I terminou-se ter de recorrer a abertura de montagem em cada ILDASM até que eu encontrei o que estava fazendo referência a uma versão mais antiga do conjunto dependente.

Eu fiz tentar usar MSBUILD do VS 2010 Beta 2 (como o artigo Ligação indicou que este foi corrigido na próxima versão do CLR), mas que não forneceu mais detalhes ou (Beta pós 2 talvez fixo)

Existe uma abordagem melhor (mais automatizado)?

Foi útil?

Solução

Alterar o "MSBuild compilação de projeto verbosidade de saída" para "detalhes" ou acima. Para fazer isso, siga estes passos:

  1. abrir o diálogo Opções ( Ferramentas -> Opções ... ).
  2. Na árvore à esquerda, selecione o projetos e soluções nó e selecione Criar e executar .
    • . Nota: Se este nó não aparecer, certifique-se de que a caixa de seleção na parte inferior da caixa de diálogo Mostrar todas as configurações é verificado
  3. Na página Ferramentas / Opções que aparece, defina o MSBuild saída da compilação projeto verbosidade nível para a definição apropriada dependendo da versão:

  4. Criar o projeto e olhar na janela de saída.

Confira as mensagens MSBuild. A tarefa ResolveAssemblyReferences, que é a tarefa da qual MSB3247 é originário, devem ajudar a depurar este problema particular.

O meu caso específico era uma referência incorrecta para SqlServerCe. Ver abaixo. Eu tinha dois projectos referenciando duas versões diferentes do SqlServerCe. Fui para o projeto com a versão mais antiga, retirou a referência, e depois acrescentou a referência correta.

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.

Você não tem que abrir cada conjunto para determinar as versões dos assemblies referenciados.

  • Você pode verificar as propriedades de cada referência.
  • Abra as propriedades do projeto e verificar as versões da seção Referências.
  • Abra os projetos com um editor de texto.
  • Use Net Reflector.

Outras dicas

Mike Hadlow tem href="http://mikehadlow.blogspot.co.uk/2011/02/asmspy-little-tool-to-help-fix-assembly.html" postada um pouco console app chamado AsmSpy que bastante bem lista referências de cada montagem:

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

Esta é uma maneira muito mais rápido para chegar ao fundo do aviso MSB3247, do que dependem da saída de MSBuild.

Às vezes @AMissico resposta não é suficiente. No meu caso, eu não poderia encontrar o erro nas janelas de saída, então eu decidi criar um arquivo de log e analisá-lo, fazendo as seguintes etapas:

  1. Como salvar o log de compilação para um arquivo ... https: / /msdn.microsoft.com/en-us/library/ms171470.aspx

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

  2. Encontre o texto: warning MS... ou a informação advertência específica: (por exemplo, linha 9293) Found conflicts between different versions... e todos os detalhes do erro de conflito será acima desta mensagem (por exemplo, linha 9277) There was a conflicts between... Localizar a mensagem de erro

Visual Studio 2013

Eu achei que (pelo menos no Visual Studio 2010), você precisa definir a verbosidade de saída para, pelo menos detalhado para ser capaz de detectar o problema.

Pode ser que o meu problema era uma referência que anteriormente era uma referência GAC, mas que não foi o caso após reinstalação da minha máquina.

Este aviso gerado por padrão ASP.NET MVC 4 beta ver aqui

Em, qualquer conjurar esta advertência pode ser eliminado editando manualmente o .csproj para o seu projeto.

modificar ........: Incluir Referência = "System.Net.Http"

para ler ......: Incluir Referência = "System.Net.Http, versão = 4.0.0.0"

Eu tive o mesmo erro e não conseguiu descobrir isso com as outras respostas. Descobri que podemos "Consolidar" pacotes NuGet.

  1. Botão direito do mouse sobre a solução
  2. Clique em Gerenciar Pacotes NuGet
  3. guia e atualização Consolidar para a mesma versão.

Use um leitor de dependência

Usando dep.exe você pode listar todas as dependências aninhadas de uma pasta inteira. Combinado com ferramentas Unix, como grep ou awk, ele pode ajudá-lo a resolver o seu problema

montagens Encontrando sendo referenciado em mais de uma versão

$ 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            

Esta linha de comandos obscuros corridas dep.exe em seguida, envia a saída duas vezes para awk para

  • colocar o pai e criança em uma única coluna (por padrão cada linha contém uma mãe e uma criança a expressar o fato de que este pai depende dessa criança)
  • em seguida, fazer uma espécie de 'grupo por' usando uma matriz associativa

Compreender como esta assembléia foi puxado na sua bin

$ 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 

Neste exemplo, a ferramenta iria mostrar-lhe que System.Web.Http 5.2.3 vem de sua dependência para FooLib enquanto a versão 4.0.0 vem de BarLib.

Em seguida, você tem a escolha entre

  • convencer os donos das libs usar a mesma versão
  • parada usando um deles
  • acrescentando redirecionamentos obrigatório em seu arquivo de configuração para usar a versão mais recente

Como executar essas coisa no Windows

Se você não tem um tipo de shell unix você precisará baixar um antes de ser capaz de executar awk grepand. Tente um dos seguintes procedimentos

Eu tive esse problema também e usado o conselho de AMissico também descobrir o problema (embora teve que nível de detalhamento conjunto de detalhes.

O problema era, na verdade, bastante simples, embora depois de encontrar o culpado.

Fundo: Eu atualizei meu projeto de VS2008 para VS2010. Em VS2008 o quadro alvo era de 3,5 e quando Trouxe-lo em VS2010 I transferido para 4 (Completa). Eu também atualizou alguns componentes de terceiros, incluindo relatórios de cristal.

Acontece que a maioria das referências do sistema onde apontando para a versão 4.0.0.0, mas um casal não tinha sido alterado automaticamente (Sistema e System.Web.Services) e ainda estavam olhando para 2.0.0.0. Crystal Reports é referência 4.0.0.0 e por isso este era o lugar onde os conflitos foram ocorrendo. Basta colocar o cursor na primeira biblioteca do Sistema no explorador solução, cursor para baixo na lista e procurando quaisquer referências a 2.0.0.0, remoção e re-adicionando mais recente 4.0.0.0 versão fez o truque.

O estranho foi que a maioria das referências tinha sido atualizado corretamente e se não fosse para o Crystal Reports, provavelmente eu nunca tinha notado ...

Eu fiz uma aplicação baseada em aplicação de Mike Hadlow: AsmSpy .

Meu aplicativo é um aplicativo WPF com interface gráfica e pode ser baixado a partir de minha casa webserver: AsmSpyPlus. exe .

Código está disponível em: GitHub

Gui Sample

Como mencionado aqui , você precisa remover as referências não utilizadas e as advertências irá.

ASP.NET gerente de construção é construir o site, passando por as pastas em ordem alfabética, e para cada pasta que descobre que as dependências e cria as dependências primeiro e depois a pasta selecionada.

Neste caso, a pasta problemático que é ~ / controlos, é seleccionado para ser construído no início, de ainda uma razão desconhecida, ele cria alguns dos controlos não como uma separada de montagem em vez de dentro do mesmo conjunto como outros controlos (parece estar ligada ao fato de que alguns controles são dependentes de outros controles na mesma pasta).

Então, a próxima pasta que é construído (~ / File-Center / Control) é dependente da pasta raiz ~ / que é dependente de ~ / Controls, de modo a pasta ~ / Controls está sendo construída novamente só que desta vez os controles que foram separadas para a sua própria montagem está agora unida à mesma montagem como outros controlos com o conjunto separados ainda a ser referenciada.

Portanto, neste ponto 2 montagem (pelo menos) possuem os mesmos controlos e a construção falhar.

Embora ainda não sei por que isso aconteceu, fomos capazes de trabalhar em torno dele, alterando os controles pasta nome para ZControls, desta forma ele não é construído antes ~ / File-Center / Controle, somente depois e desta forma ele é construído como deveria.

Quick Fix:

Botão direito do mouse na solução -> Gerenciar pacotes NuGet para solução -> Em Consolidar você pode ver se existem diferentes versões do mesmo pacote foram instalados. Desinstalar versões diferentes e instalar o mais recente.

Às vezes AutoGenerateBindingRedirects não é suficiente (mesmo com GenerateBindingRedirectsOutputType ). Procura de todas as entradas There was a conflict e corrigi-los manualmente, um por um pode ser tedioso, então eu escrevi um pequeno pedaço de código que analisa a saída do log e gera-los para você (lixeiras para 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);

Dica: use MSBuild binário e estruturado Visualizador de Log e só gerar redirecionamentos para os conflitos de ligação no projeto que emite o aviso (ou seja, apenas passado essas linhas there was a conflict para o arquivo de texto de entrada para o código acima [AssemblyConflicts.txt]).

A maneira mais simples, sem, sem uma tomada em consideração das dependências (internos):

  1. Open "Solution Explorer".
  2. Clique em "Mostrar todos os arquivos"
  3. Expanda "Referências"
  4. Você verá uma (ou mais) de referência (s) com o ícone de um pouco diferente do que o resto. Normalmente, é com caixa amarela sugerindo que você tome uma nota do mesmo. Basta removê-lo.
  5. Adicione as costas de referência e compilar o código.
  6. Isso é tudo.

No meu caso, houve um problema com referência MySQL. De alguma forma, eu poderia listar três versões do mesmo sob a lista de todas as referências disponíveis. Segui processo de 1 a 6 acima e funcionou para mim.

Visual Studio para além Mac Comunidade:

Como resposta de AMissico exige a mudança do nível de log, e nem ASMSpy nem ASMSpyPlus estão disponíveis como uma solução multi-plataforma, aqui está uma pequena adição para Visual Studio para Mac:

https://docs.microsoft.com/en -us / VisualStudio / mac /-e-construção compilar

É em Visual comunitários estúdio ? Configurações ... ? Projetos ? Desenvolver Log ? verbosidade

Se você tiver ReSharper, remova todas as referências não utilizado na sua solução.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top