Comment corriger l'erreur «L'assembly référencé n'a pas de nom fort»?

242

J'ai ajouté un assembly faiblement nommé à mon projet Visual Studio 2005 (qui est fortement nommé). Je reçois maintenant l'erreur:

"L'assembly référencé 'xxxxxxxx' n'a pas de nom fort"

Dois-je signer cette assemblée tierce?

ng5000
la source
1
Cela peut sembler une astuce idiote, mais si vous constatez que votre assemblage n'est pas signé quoi que vous fassiez, vérifiez vos paramètres de construction; rappelez-vous que VS ne supprime pas les autres architectures (tout processeur, x64, etc.) lorsque vous reconstruisez / nettoyez, vous pouvez donc consulter une DLL obsolète d'une autre architecture.
2018

Réponses:

213

Pour éviter cette erreur, vous pouvez soit:

  • Chargez l'assemblage dynamiquement, ou
  • Signez l'assemblée tierce.

Vous trouverez des instructions sur la signature d'assemblages tiers dans .NET-fu: signature d'un assemblage non signé (sans signature différée) .

Signature d'assemblages tiers

Le principe de base pour signer un parti tiers est de

  1. Démontez l'assemblage à l'aide ildasm.exeet enregistrez le langage intermédiaire (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Reconstruisez et signez l'assembly:

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

Correction de références supplémentaires

Les étapes ci-dessus fonctionnent correctement, sauf si votre assembly tiers ( A.dll ) fait référence à une autre bibliothèque ( B.dll ) qui doit également être signée. Vous pouvez désassembler, reconstruire et signer à la fois A.dll et B.dll à l'aide des commandes ci-dessus, mais au moment de l'exécution, le chargement de B.dll échouera car A.dll a été initialement construit avec une référence à la version non signée de B.dll .

La solution à ce problème consiste à corriger le fichier IL généré à l'étape 1 ci-dessus. Vous devrez ajouter le jeton de clé publique de B.dll à la référence. Vous obtenez ce jeton en appelant

sn -Tp B.dll 

ce qui vous donnera la sortie suivante:

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

La dernière ligne contient le jeton de clé publique. Vous devez ensuite rechercher l'IL de A.dll pour la référence à B.dll et ajouter le jeton comme suit:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}
Dirk Vollmar
la source
2
La signature de l'assemblage est donc une option, je ne souhaite ni charger l'assemblage dynamiquement ni le signer. Je sais qu'une dénomination forte concerne le Global Assembly Cache (GAC). Malgré cela, je ne veux pas que mes assemblages fassent partie du GAC et ils ne sont pas non plus COM-visibles. Je me souviens partiellement de quelque chose que nous pouvons faire qui permettra l'utilisation de cet assemblage sans le signer. Il se trouve quelque part dans les propriétés des options. Suis-je sur la bonne voie en voulant suivre cette voie?
Will Marcouiller le
27
Vous pouvez utiliser des assemblys non signés si votre assemblage est également non signé.
JO.
2
Le lien vers .NET-fu est une ressource géniale
TheDude
2
Bien que les étapes ci-dessus fonctionnent dans «la plupart» des situations, elles prennent énormément de temps et sont sujettes aux erreurs et échouent entre autres avec les références d'assembly ami. Utilisez simplement cet utilitaire pour tout faire automatiquement (plug sans vergogne): stackoverflow.com/a/19459609/564726
BrutalDev
1
@Roel J'ai détaillé le processus ici delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude
98

Développez le fichier de projet qui utilise le projet qui n'a pas "de clé de nom fort" et recherchez le .snkfichier (.StrongNameKey).

Parcourez ce fichier dans l' Explorateur Windows (juste pour savoir où il se trouve).

De retour dans Visual Studio dans le projet qui "n'a pas de clé de nom fort", faites

  • Clic droit sur le fichier projet
  • Sélectionnez Propriétés
  • Sélectionnez "Onglet Signature" (à gauche)
  • Cochez la case "Signer l'assemblage"
  • Ensuite, <Browse>vers le .snkfichier que vous avez trouvé plus tôt

Cela devrait faire l'affaire. Cela a résolu un problème pour moi pour un projet utilisant un formulaire dans un autre projet dans la même solution.

J'espère que ça aide.

MrOli3000
la source
Si je ne voulais pas signer mon montage je ne l'aurais pas signé dès le départ!
mohas
Si vous ne trouvez pas le fichier .snk: ouvrez les propriétés du projet (du projet utilisant le projet avec l'erreur "nom fort"), onglet Signature. Vous y verrez le fichier utilisé pour signer le projet (n'est pas toujours un fichier avec l'extension .snk). Copiez simplement ce paramètre dans l'autre projet.
Coder14
Comme le souligne MrOli3000, cela fonctionne UNIQUEMENT s'il y a une solution qui manque le fichier de clé de nom fort. S'il existe plusieurs projets qui référenceraient le projet non signé, il vaut mieux créer un nouveau fichier de clé de nom fort pour éviter tout conflit. Dans mon cas, la solution n'a pas été créée et je tournais en rond pour essayer de résoudre le problème. Depuis VS2017, le format est .pfx et non .snk, mais les étapes sont les mêmes - Faites un clic droit sur la solution et choisissez les propriétés. Dans les onglets répertoriés à gauche, choisissez "Signature". Cochez la case et sélectionnez nouveau ... donnez un nom! et Voila! c'est fait!)
Raj
59

Je cherchais une solution au même problème et décocher l'option "Signer l'assemblage" fonctionne pour moi:

entrez la description de l'image ici

(comme vous pouvez le remarquer, la capture d'écran provient de VS2010 mais j'espère que cela aidera quelqu'un)

Mars Robertson
la source
Je ne vérifie pas ce paramètre dans mon projet MVC. Mais il se plaint toujours d'une des dépendances. Existe-t-il un autre paramètre pour MVC?
Hamid Mayeli
51

J'ai écrit un outil pour assembler automatiquement les enseignes avec des noms forts, y compris ceux dont vous n'avez pas le code source ou les projets qui ont été abandonnés. Il utilise la plupart des techniques décrites dans les réponses de manière simple sans aucun des défauts ou des inconvénients des outils existants ou des instructions datées.

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

J'espère que cela aidera toute personne qui doit signer une assemblée tierce sans avoir à sauter à travers des cerceaux pour y arriver.

BrutalDev
la source
40

Vous pouvez utiliser des assemblys non signés si votre assemblage est également non signé.

Alexandr Nikitin
la source
23

La signature de l'assemblée tierce a fonctionné pour moi:

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

EDIT : J'ai appris qu'il est utile de publier des étapes au cas où l'article lié ne serait plus valide. Tout le mérite revient à Hiren Khirsaria :

  1. Exécutez l'invite de commande de Visual Studio et accédez au répertoire où se trouve votre DLL.

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

  2. Créez maintenant le fichier IL en utilisant la commande ci-dessous.

    D:/hiren> ildasm /all /out=Test.il Test.dll (cette commande génère la bibliothèque de code)

  3. Générez une nouvelle clé pour signer votre projet.

    D:/hiren> sn -k mykey.snk

  4. Signez maintenant votre bibliothèque à l'aide de la ilasmcommande.

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

mateuscb
la source
Votre lien a fait l'affaire! Merci! Et ça explique comment créer mykey.snk (les autres réponses ne disent pas comment)
Nicolas VERHELST
15

Comment signer un assemblage tiers non signé

  1. Ouvrez l'invite de commande du développeur pour Visual Studio. Cet outil est disponible dans vos programmes Windows et peut être trouvé en utilisant la recherche par défaut de Windows.
  2. Assurez-vous que votre invite a accès aux outils suivants en les exécutant une fois: sn ildasmetilasm
  3. Accédez au dossier où se trouve votre Cool.Library.dll
  4. sn –k Cool.Library.snk pour créer une nouvelle paire de clés
  5. ildasm Cool.Library.dll /out:Cool.Library.il démonter la bibliothèque
  6. move Cool.Library.dll Cool.Library.unsigned.dll conserver la bibliothèque d'origine comme sauvegarde
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk remonter la bibliothèque avec un nom fort
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"pour obtenir le nom complet de l'assembly. Vous aurez besoin de ce bit si vous devez référencer la DLL dans des fichiers de configuration externes comme web.config ou app.config.
Martin Devillers
la source
6

J'ai eu ce problème pour une application qui était fortement nommée, puis j'ai dû la changer afin de référencer un assemblage non fortement nommé, j'ai donc décoché 'Signer l'assemblage' dans la section Signature des propriétés du projet, mais elle s'est toujours plainte. J'ai pensé que ça devait être un artefact quelque part causant le problème puisque j'ai fait tout le reste correctement et c'était juste ça. J'ai trouvé et supprimé la ligne: [assembly: AssemblyKeyFile ("yourkeyfilename.snk")] de son fichier assemblyInfo.cs. Ensuite, pas de plaintes de construction après cela.

Joe
la source
Je vous remercie! En raison de votre réponse, je le revérifie pour mon problème (ClosedXML) et j'ai également trouvé le package de nuget ClosedXML.Signed.
Kiryl
6

Je rencontrais cela avec une DLL ServiceStack que j'avais installée avec nuget. Il s'est avéré qu'il y avait un autre ensemble de DLL disponibles étiquetées signées. Cela ne sera pas la réponse pour tout le monde, mais vous devrez peut-être simplement vérifier une version signée existante de votre assemblage.ServiceStack.Signed

Henry Crans
la source
2

Pour moi, mon problème était que j'avais deux des mêmes packages NuGet installés avec des versions différentes.

Demodave
la source
2

Suppression de la coche "Signer l'assemblage" sous la "Signature" onglet fonctionne comme l'a dit @Michal Stefanow.

Ajouter ici est le moyen le plus simple de signer vos propres fichiers et / ou les fichiers d'autres personnes. Il vous suffit d'ajouter cette ligne sous la "ligne de commande d'événement post-build":

"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)"

Vous pouvez signer les fichiers d'autres personnes ou vos propres fichiers et autant que vous le souhaitez.

entrez la description de l'image ici

Pabinator
la source
5
Il s'agit d'un type de signature différent. Ce que l'OP demande, c'est comment signer un assembly .NET avec un nom fort. Vous montrez comment signer un exécutable avec un certificat de signature de code. Différentes choses.
Blue Toque
2

Vieille question, mais je suis surpris que personne n'ait encore mentionné ilmerge. ilmerge provient de Microsoft, mais n'est pas fourni avec VS ou les SDK. Vous pouvez cependant le télécharger à partir d' ici . Il existe également un référentiel github . Vous pouvez également installer à partir de nuget:

PM>Install-Package ilmerge

Utiliser:

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

Si nécessaire, vous pouvez générer votre propre fichier de clés à l'aide de sn (à partir de VS):

sn -k key.snk
Jahmic
la source
1
J'ai eu le problème avec WireMock.Net, j'ai finalement réussi à le faire fonctionner, mais il m'a fallu un peu de temps pour comprendre les commandes PowerShell. En particulier, tout le tas d'arguments / lib pour finalement obtenir ILMerge pour signer l'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

Situation: vous aviez le projet A, B, C, D dans la solution X, Y

Projet A, B, C en X Projet A, C, D en Y

J'ai besoin d'utiliser le projet C dans le projet A, mais plus tard, je ne l'utilise pas. Dans le projet de débogage bin A, il y avait C.dll.

Si je compile la solution X, tout va bien (dans cette solution, je supprime la référence A -> C.), mais dans la solution Y, j'obtiens ce problème.

La solution consiste à supprimer C.dll dans le projet A bin Debug

Martin9032
la source
0

Assurez-vous d'abord que tous les packages nuget sont à la même version dans tous les projets de votre solution. Par exemple, vous ne voulez pas qu'un projet fasse référence à NLog 4.0.0.0 et qu'un autre projet fasse référence à NLog 4.1.0.0. Essayez ensuite de réinstaller les packages nuget avec

Update-Package -reinstall

J'ai eu 3 assemblées tierces qui ont été référencées par mon assemblée A et seulement 2 ont été incluses dans les références par mon assemblée B qui a également référencé A.

La référence manquante à l'assembly tiers a été ajoutée par la commande update package et l'erreur a disparu.

Markus
la source