Como corrigir o erro "O conjunto referenciado não tem um nome forte"?

241

Adicionei um assembly com nome fraco ao meu projeto do Visual Studio 2005 (que é fortemente nomeado). Agora estou recebendo o erro:

"O conjunto referenciado 'xxxxxxxx' não tem um nome forte"

Preciso assinar esta montagem de terceiros?

ng5000
fonte
1
Isso pode parecer uma dica boba, mas se você achar que sua montagem não está sendo assinada, não importa o que você faça, verifique as configurações de compilação; lembre-se de que o VS não limpa outras arquiteturas (qualquer CPU, x64 etc.) quando você reconstrói / limpa, para que você possa olhar para uma dll desatualizada de outra arquitetura.
Jrh 10/1018

Respostas:

213

Para evitar esse erro, você pode:

  • Carregue a montagem dinamicamente ou
  • Assine a montagem de terceiros.

Você encontrará instruções sobre como assinar assemblies de terceiros no .NET-fu: Assinando um assembly não assinado (sem atrasar a assinatura) .

Assinando Assembleias de Terceiros

O princípio básico para assinar uma sede é

  1. Desmonte a montagem usando ildasm.exee salve o idioma intermediário (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Reconstrua e assine a montagem:

    ilasm /dll /key=myKey.snk thirdPartyLib.il

Corrigindo referências adicionais

As etapas acima funcionam bem, a menos que seu assembly de terceiros ( A.dll ) faça referência a outra biblioteca ( B.dll ) que também precisa ser assinada. Você pode desmontar, recriar e assinar o A.dll e o B.dll usando os comandos acima, mas em tempo de execução, o carregamento do B.dll falhará porque o A.dll foi originalmente criado com uma referência à versão não assinada do B.dll .

A correção para esse problema é corrigir o arquivo IL gerado na etapa 1 acima. Você precisará adicionar o token de chave pública do B.dll à referência. Você recebe esse token chamando

sn -Tp B.dll 

que fornecerá a seguinte saída:

Microsoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.33440
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key (hash algorithm: sha1):
002400000480000094000000060200000024000052534131000400000100010093d86f6656eed3
b62780466e6ba30fd15d69a3918e4bbd75d3e9ca8baa5641955c86251ce1e5a83857c7f49288eb
4a0093b20aa9c7faae5184770108d9515905ddd82222514921fa81fff2ea565ae0e98cf66d3758
cb8b22c8efd729821518a76427b7ca1c979caa2d78404da3d44592badc194d05bfdd29b9b8120c
78effe92

Public key token is a8a7ed7203d87bc9

A última linha contém o token de chave pública. Você precisará procurar no IL do A.dll a referência ao B.dll e adicionar o token da seguinte maneira:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}
Dirk Vollmar
fonte
2
Assim, assinar a montagem é uma opção, não desejo carregar a montagem dinamicamente nem assiná-la. Eu sei que a nomeação forte é referente ao Global Assembly Cache (GAC). Apesar disso, não quero tornar minhas assembléias parte do GAC e elas também não são visíveis ao COM. Lembro-me parcialmente de algo que podemos fazer que permitirá o uso desta montagem sem assiná-la. Está em algum lugar nas propriedades das opções ou algo assim. Estou fora de pista, querendo ir por esse caminho?
Will Marcouiller 14/09/09
27
Você pode usar montagens não assinadas se sua montagem também não estiver assinada.
JO.
2
O link para .NET-fu é um recurso incrível
TheDude
2
Embora as etapas acima funcionem na "maioria" das situações, são incrivelmente demoradas e propensas a erros e falham nas referências de montagem de amigos, entre outras coisas. Basta usar este utilitário para fazer tudo automaticamente (plugue descarado): stackoverflow.com/a/19459609/564726
BrutalDev
1
@Roel Eu detalhei o processo aqui delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude
98

Expanda o arquivo de projeto que está usando o projeto que "não possui uma chave de nome forte" e procure o .snkarquivo (.StrongNameKey).

Navegue até esse arquivo no Windows Explorer (apenas para saber onde ele está).

De volta ao Visual Studio no projeto que não "possui uma chave de nome forte", faça

  • Clique com o botão direito do mouse no arquivo do projeto
  • Selecione Propriedades
  • Selecione a guia "Assinatura" (à esquerda)
  • Clique na caixa de seleção "Assinar a montagem"
  • Depois, <Browse>para o .snkarquivo que você encontrou anteriormente

Isso deve fazer o truque. Isso resolveu um problema para mim para um projeto usando um formulário dentro de outro projeto na mesma solução.

Espero que ajude.

MrOli3000
fonte
Se eu não quisesse assinar minha montagem, não a teria assinado desde o início!
mohas
Se você não encontrar o arquivo .snk: Abra as propriedades do projeto (do projeto usando o projeto com o erro "nome forte"), guia Assinatura. Lá você verá o arquivo usado para assinar o projeto (nem sempre é um arquivo com a extensão .snk). Basta copiar essa configuração para o outro projeto.
precisa saber é o seguinte
Como MrOli3000 aponta, ele funciona SOMENTE se houver uma solução que está faltando no arquivo de chave de nome forte. Se houver vários projetos que referenciam o projeto não assinado, é melhor criar um novo arquivo de chave de nome forte para evitar conflitos. No meu caso, a solução não foi criada e eu estava andando em círculos tentando consertar. No VS2017, o formato é .pfx e não .snk, mas as etapas são as mesmas - Clique com o botão direito do mouse na solução e escolha propriedades. Nas guias listadas à esquerda, escolha "Assinatura". Clique na caixa de seleção e selecione novo ... forneça um nome! e Voila! isso é feito)!
Raj
58

Eu estava procurando a solução para o mesmo problema e desmarcar a opção "Assinar a montagem" funciona para mim:

insira a descrição da imagem aqui

(como você pode notar, a captura de tela vem do VS2010, mas espero que ajude alguém)

Mars Robertson
fonte
Não verifico essa configuração no meu projeto MVC. Mas ainda está reclamando de uma das dependências. Existe alguma outra configuração para o MVC?
Hamid Mayeli 11/11/19
51

Eu escrevi uma ferramenta para criar assemblies de sinal com nome forte automaticamente, incluindo aqueles para os quais você não possui o código-fonte ou projetos que foram abandonados. Ele usa muitas das técnicas descritas nas respostas de maneira simples, sem nenhuma das falhas ou inconvenientes das ferramentas existentes ou das instruções datadas.

http://brutaldev.com/post/2013/10/18/NET-Assembly-Strong-Name-Signer

Espero que isso ajude qualquer pessoa que precise assinar uma assembléia de terceiros sem ter que pular os bastidores para chegar lá.

BrutalDev
fonte
40

Você pode usar montagens não assinadas se sua montagem também não estiver assinada.

Alexandr Nikitin
fonte
23

A assinatura da montagem de terceiros funcionou para mim:

http://www.codeproject.com/Tips/341645/Referenced-assembly-does-not-have-a-strong-name

EDIT : aprendi que é útil publicar etapas caso o artigo vinculado não seja mais válido. Todo o crédito vai para Hiren Khirsaria :

  1. Execute o prompt de comando do visual studio e vá para o diretório em que sua DLL estava localizada.

    For Example my DLL is located in D:/hiren/Test.dll

  2. Agora crie o arquivo IL usando o comando abaixo.

    D:/hiren> ildasm /all /out=Test.il Test.dll (este comando gera a biblioteca de códigos)

  3. Gere uma nova chave para assinar seu projeto.

    D:/hiren> sn -k mykey.snk

  4. Agora assine sua biblioteca usando o ilasmcomando

    D:/hiren> ilasm /dll /key=mykey.snk Test.il

mateuscb
fonte
Seu link fez o truque! E explica como criar mykey.snk (as outras respostas não dizem como)
Nicolas VERHELST
15

Como assinar um assembly de terceiros não assinado

  1. Abra o prompt de comando do desenvolvedor para o Visual Studio. Esta ferramenta está disponível nos seus programas Windows e pode ser encontrada usando a pesquisa padrão do Windows.
  2. Verifique se seu prompt tem acesso às seguintes ferramentas, executando-as uma vez: sn ildasmeilasm
  3. Navegue para a pasta onde está localizado o Cool.Library.dll
  4. sn –k Cool.Library.snk para criar um novo par de chaves
  5. ildasm Cool.Library.dll /out:Cool.Library.il desmontar a biblioteca
  6. move Cool.Library.dll Cool.Library.unsigned.dll para manter a biblioteca original como um backup
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk remontar a biblioteca com um nome forte
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"para obter o nome completo da montagem. Você precisará desse bit se precisar fazer referência à DLL em arquivos de configuração externos, como web.config ou app.config.
Martin Devillers
fonte
6

Eu tinha esse problema para um aplicativo que tinha um nome forte e tive que alterá-lo para fazer referência a um assembly com um nome não muito forte, então desmarquei a opção 'Sign the assembly' na seção Signing das propriedades do projeto, mas ele ainda reclamou. Achei que tinha que ser um artefato em algum lugar causando o problema, já que fiz todo o resto corretamente e foi exatamente isso. Encontrei e removi a linha: [assembly: AssemblyKeyFile ("yourkeyfilename.snk")] de seu arquivo assemblyInfo.cs. Então não crie reclamações depois disso.

Joe
fonte
Obrigado! Por causa da sua resposta, verifique novamente o meu problema (ClosedXML) e encontrei o pacote de nuget ClosedXML.Signed também.
Kiryl 16/04
6

Eu estava correndo para isso com uma dll ServiceStack que eu tinha instalado com nuget. Acontece que havia outro conjunto de dlls disponíveis rotuladas como assinadas. Não será a resposta para todos, mas pode ser necessário apenas verificar se há uma versão assinada do seu assembly.ServiceStack.Signed

Henry Crans
fonte
2

Para mim, meu problema era que eu tinha dois dos mesmos pacotes NuGet instalados com versões diferentes.

Demodave
fonte
2

A remoção da marca de seleção "Assinar a montagem" na guia "Assinatura" funciona como disse @Michal Stefanow.

Adicionar aqui é a maneira mais simples de assinar seus próprios arquivos e / ou arquivos de outras pessoas. Você só precisa adicionar esta linha sob a "linha de comando do evento Pós-compilação":

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\signtool.exe" sign /f "$(ProjectDir)\YourPfxFileNameHere.pfx" /p YourPfxFilePasswordHere /d "Your software title here" /du http://www.yourWebsiteHere.com /t http://timestamp.verisign.com/scripts/timstamp.dll /v "$(BaseOutputPath)$(TargetFileName)"

Você pode assinar os arquivos de outras pessoas ou seus próprios arquivos, e quantos quiser.

insira a descrição da imagem aqui

Pabinator
fonte
5
Esse é um tipo diferente de assinatura. O que o OP está perguntando é como assinar um assembly .NET com um nome forte. Você está mostrando como assinar um executável com um certificado de assinatura de código. Coisas diferentes.
Blue Toque
2

Pergunta antiga, mas estou surpreso que ninguém tenha mencionado ilmerge ainda. O ilmerge é da Microsoft, mas não é fornecido com o VS ou os SDKs. Você pode baixá-lo aqui embora. Há também um repositório do github . Você também pode instalar a partir do nuget:

PM>Install-Package ilmerge

Usar:

ilmerge assembly.dll /keyfile:key.snk /out:assembly.dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /ndebug

Se necessário, você pode gerar seu próprio arquivo de chave usando sn (do VS):

sn -k key.snk
Jahmic
fonte
1
Eu tive o problema com o WireMock.Net, finalmente o fiz funcionar, mas levei um tempo para descobrir os comandos do PowerShell. Particularmente, todo o conjunto de argumentos / lib para finalmente levar o ILMerge a assinar o assembly.
François
1> Register-PackageSource -ProviderName NuGet -Name NuGet -Location http://www.nuget.org/api/v2
François
2> Install-Package -Name ILMerge
François
3> $env:path += ';C:\Program Files\PackageManagement\NuGet\Packages\ilmerge.2.14.1208\tools'
François
4> ILMerge.exe .\packages\WireMock.Net.1.0.4.2\lib\net452\WireMock.Net.dll /keyfile:key.snk /out:WireMock.Net.dll /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /ndebug /lib:.\packages\Newtonsoft.Json.10.0.3\lib\net45\ /lib:.\packages\Handlebars.Net.1.9.0\lib\net40 /lib:.\packages\SimMetrics.Net.1.0.4\lib\net45 /lib:.\packages\Microsoft.Owin.2.0.2\lib\net45 /lib:.\packages\Owin.1.0\lib\net40 /lib:.\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45 /lib:.\packages\MimeKitLite.2.0.1\lib\net45 /lib:.\packages\XPath2.1.0.5.1\lib\net40 /lib:.\packages\RestEase.1.4.4\lib\net45
François
1

Situação: você tinha o projeto A, B, C, D na solução X, Y

Projeto A, B, C em X Projeto A, C, D em Y

Preciso usar o projeto C no projeto A, mas depois não uso. No projeto de depuração bin A tinha C.dll.

Se eu compilar a solução X, tudo de bom (nesta solução, excluo a referência A -> C.), mas na solução Y, recebo esse problema.

A solução é excluir C.dll no projeto A bin Debug

Martin9032
fonte
0

Primeiro, verifique se todos os pacotes de nuget estão na mesma versão em todos os projetos em sua solução. por exemplo, você não deseja que um projeto faça referência ao NLog 4.0.0.0 e outro projeto faça referência ao NLog 4.1.0.0. Em seguida, tente reinstalar pacotes nuget com

Update-Package -reinstall

Eu tinha 3 assemblies de terceiros que foram referenciados pelo meu assembly A e apenas 2 foram incluídos nas referências do meu assembly B, que também referenciaram A.

A referência ausente ao assembly de terceiros foi adicionada pelo comando update package e o erro desapareceu.

Markus
fonte