Wie kann der Fehler "Referenzierte Baugruppe hat keinen starken Namen" behoben werden?

241

Ich habe meinem Visual Studio 2005- Projekt eine schwach benannte Assembly hinzugefügt (die stark benannt ist). Ich erhalte jetzt den Fehler:

"Die referenzierte Assembly 'xxxxxxxx' hat keinen starken Namen."

Muss ich diese Versammlung von Drittanbietern unterschreiben?

ng5000
quelle
1
Dies mag sich nach einem dummen Tipp anhören, aber wenn Sie feststellen, dass Ihre Assembly nicht signiert wird, egal was Sie tun, überprüfen Sie Ihre Build-Einstellungen. Denken Sie daran, dass VS andere Architekturen (CPU, x64 usw.) beim Neuerstellen / Bereinigen nicht löscht, sodass Sie möglicherweise eine veraltete DLL einer anderen Architektur betrachten.
jrh

Antworten:

213

Um diesen Fehler zu vermeiden, können Sie entweder:

  • Laden Sie die Baugruppe dynamisch oder
  • Unterzeichnen Sie die Versammlung eines Drittanbieters.

Anweisungen zum Signieren von Assemblys von Drittanbietern finden Sie in .NET-fu: Signieren einer nicht signierten Assembly (ohne verzögerte Signierung) .

Unterzeichnung von Baugruppen von Drittanbietern

Das Grundprinzip, um eine Thirp-Party zu unterzeichnen, ist zu

  1. Zerlegen Sie die Baugruppe mit ildasm.exeder Zwischensprache (IL) und speichern Sie sie:

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Erstellen Sie die Baugruppe neu und unterschreiben Sie sie:

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

Zusätzliche Referenzen korrigieren

Die obigen Schritte funktionieren einwandfrei, es sei denn, Ihre Drittanbieter-Assembly ( A.dll ) verweist auf eine andere Bibliothek ( B.dll ), die ebenfalls signiert werden muss. Sie können A.dll und B.dll mit den obigen Befehlen zerlegen, neu erstellen und signieren. Zur Laufzeit schlägt das Laden von B.dll jedoch fehl, da A.dll ursprünglich mit einem Verweis auf die nicht signierte Version von B.dll erstellt wurde .

Die Lösung für dieses Problem besteht darin, die in Schritt 1 oben generierte IL-Datei zu patchen. Sie müssen das öffentliche Schlüsseltoken von B.dll zur Referenz hinzufügen. Sie erhalten dieses Token, indem Sie anrufen

sn -Tp B.dll 

Das gibt Ihnen die folgende Ausgabe:

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

Die letzte Zeile enthält das Token für den öffentlichen Schlüssel. Sie müssen dann die IL von A.dll nach dem Verweis auf B.dll durchsuchen und das Token wie folgt hinzufügen:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}
Dirk Vollmar
quelle
2
Daher ist das Signieren der Assembly eine Option. Ich möchte die Assembly weder dynamisch laden noch signieren. Ich weiß, dass der Global Assembly Cache (GAC) eine starke Benennung aufweist. Trotzdem möchte ich meine Baugruppen nicht zum GAC machen und sie sind auch nicht COM-sichtbar. Ich erinnere mich teilweise an etwas, das wir möglicherweise tun, um die Verwendung dieser Assembly ohne Unterzeichnung zu ermöglichen. Es ist irgendwo in den Optionen Eigenschaften oder so. Bin ich nicht auf dem richtigen Weg, um diesen Weg zu gehen?
Will Marcouiller
27
Sie können nicht signierte Assemblys verwenden, wenn Ihre Assembly ebenfalls nicht signiert ist.
ABl.
2
Der Link zu .NET-fu ist eine großartige Ressource
TheDude
2
Obwohl die oben genannten Schritte in "den meisten" Situationen funktionieren, sind sie unglaublich zeitaufwändig und fehleranfällig und schlagen unter anderem mit Verweisen auf die Assembly von Freunden fehl. Verwenden Sie einfach dieses Dienstprogramm, um alles automatisch zu erledigen (schamloser Stecker): stackoverflow.com/a/19459609/564726
BrutalDev
1
@Roel Ich habe den Prozess hier detailliert beschrieben. Delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude
98

Erweitern Sie die Projektdatei, die das Projekt verwendet, das keinen "starken Namensschlüssel" hat, und suchen Sie nach der .snkDatei (.StrongNameKey).

Navigieren Sie im Windows Explorer zu dieser Datei (nur damit Sie wissen, wo sie sich befindet).

Zurück in Visual Studio im Projekt, das keinen "starken Namensschlüssel" hat, tun Sie dies

  • Klicken Sie mit der rechten Maustaste auf die Projektdatei
  • Wählen Sie Eigenschaften
  • Wählen Sie "Registerkarte Signieren" (links)
  • Aktivieren Sie das Kontrollkästchen "Baugruppe signieren".
  • Dann <Browse>zu der .snkDatei, die Sie zuvor gefunden haben

Das sollte den Trick machen. Dies löste für mich ein Problem für ein Projekt, indem ich ein Formular in einem anderen Projekt in derselben Lösung verwendete.

Ich hoffe, es hilft.

MrOli3000
quelle
Wenn ich meine Versammlung nicht unterschreiben wollte, hätte ich sie nicht von Anfang an unterschrieben!
Mohas
Wenn Sie die .snk-Datei nicht finden: Öffnen Sie die Projekteigenschaften (des Projekts, das das Projekt mit dem Fehler "Starker Name" verwendet) auf der Registerkarte Signieren. Dort sehen Sie die Datei, mit der das Projekt signiert wurde (nicht immer eine Datei mit der Erweiterung .snk). Kopieren Sie diese Einstellung einfach in das andere Projekt.
Coder14
Wie MrOli3000 hervorhebt, funktioniert es NUR, wenn es eine Lösung gibt, bei der die Schlüsseldatei mit starkem Namen fehlt. Wenn es mehrere Projekte gibt, die auf das nicht signierte Projekt verweisen, sollten Sie eine neue Schlüsseldatei mit starkem Namen erstellen, um Konflikte zu vermeiden. In meinem Fall hat sich die Lösung nicht entwickelt, und ich habe im Kreis versucht, das Problem zu beheben. Ab VS2017 ist das Format .pfx und nicht .snk, aber die Schritte sind dieselben - Klicken Sie mit der rechten Maustaste auf die Lösung und wählen Sie Eigenschaften. Wählen Sie auf den links aufgelisteten Registerkarten "Signieren". Aktivieren Sie das Kontrollkästchen und wählen Sie Neu ... geben Sie einen Namen an! und Voila! es ist geschafft!)
Raj
58

Ich habe nach einer Lösung für das gleiche Problem gesucht und das Deaktivieren der Option "Baugruppe signieren" funktioniert für mich:

Geben Sie hier die Bildbeschreibung ein

(Wie Sie vielleicht bemerken, stammt der Screenshot von VS2010, aber hoffentlich hilft er jemandem.)

Mars Robertson
quelle
Ich überprüfe diese Einstellung in meinem MVC-Projekt nicht. Aber es beschwert sich immer noch über eine der Abhängigkeiten. Gibt es eine andere Einstellung für MVC?
Hamid Mayeli
51

Ich habe ein Tool geschrieben, mit dem Zeichenbaugruppen mit starken Namen automatisch erstellt werden können, einschließlich solcher, für die Sie keinen Quellcode haben, oder für Projekte, die abgebrochen wurden. Es verwendet viele der in den Antworten beschriebenen Techniken auf einfache Weise, ohne die Mängel oder Nachteile vorhandener Werkzeuge oder datierter Anweisungen.

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

Ich hoffe, dies hilft allen, die eine Versammlung von Drittanbietern unterzeichnen müssen, ohne durch Reifen springen zu müssen, um dorthin zu gelangen.

BrutalDev
quelle
40

Sie können nicht signierte Assemblys verwenden, wenn Ihre Assembly ebenfalls nicht signiert ist.

Alexandr Nikitin
quelle
23

Die Unterzeichnung der Versammlung von Dritten hat für mich funktioniert:

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

BEARBEITEN : Ich habe gelernt, dass es hilfreich ist, Schritte zu posten, falls der verlinkte Artikel nicht mehr gültig ist. Alle Kredite gehen an Hiren Khirsaria :

  1. Führen Sie die Visual Studio-Eingabeaufforderung aus und wechseln Sie in das Verzeichnis, in dem sich Ihre DLL befindet.

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

  2. Erstellen Sie nun die IL-Datei mit dem folgenden Befehl.

    D:/hiren> ildasm /all /out=Test.il Test.dll (Dieser Befehl generiert die Codebibliothek.)

  3. Generieren Sie einen neuen Schlüssel, um Ihr Projekt zu signieren.

    D:/hiren> sn -k mykey.snk

  4. Signieren Sie nun Ihre Bibliothek mit dem ilasmBefehl.

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

mateuscb
quelle
Dein Link hat es geschafft! Danke! Und es erklärt, wie man mykey.snk erstellt (die anderen Antworten sagen nicht, wie)
Nicolas VERHELST
15

So unterschreiben Sie eine nicht signierte Versammlung eines Drittanbieters

  1. Öffnen Sie die Developer Command Prompt für Visual Studio. Dieses Tool ist in Ihren Windows-Programmen verfügbar und kann mithilfe der Standard-Windows-Suche gefunden werden.
  2. Stellen Sie sicher, dass Ihre Eingabeaufforderung Zugriff auf die folgenden Tools hat, indem Sie sie einmal ausführen: sn ildasmundilasm
  3. Navigieren Sie zu dem Ordner, in dem sich Ihre Cool.Library.dll befindet
  4. sn –k Cool.Library.snk um ein neues Schlüsselpaar zu erstellen
  5. ildasm Cool.Library.dll /out:Cool.Library.il die Bibliothek zu zerlegen
  6. move Cool.Library.dll Cool.Library.unsigned.dll um die ursprüngliche Bibliothek als Backup zu behalten
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk die Bibliothek mit einem starken Namen wieder zusammenzusetzen
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"um den vollständig qualifizierten Namen der Baugruppe zu erhalten. Sie benötigen dieses Bit, wenn Sie in externen Konfigurationsdateien wie web.config oder app.config auf die DLL verweisen müssen.
Martin Devillers
quelle
6

Ich hatte dieses Problem für eine App mit starkem Namen und musste es dann ändern, um auf eine nicht stark benannte Assembly zu verweisen. Daher habe ich im Abschnitt Signieren der Projekteigenschaften das Kontrollkästchen "Assembly signieren" deaktiviert, es wurde jedoch weiterhin beanstandet. Ich dachte, es müsste irgendwo ein Artefakt sein, das das Problem verursacht, da ich alles andere richtig gemacht habe und es genau das war. Ich habe die folgende Zeile gefunden und entfernt: [Assembly: AssemblyKeyFile ("yourkeyfilename.snk")] aus der Datei assemblyInfo.cs. Danach keine Build-Beschwerden mehr.

Joe
quelle
Danke dir! Aufgrund Ihrer Antwort überprüfe ich es erneut auf mein Problem (ClosedXML) und habe auch das ClosedXML.Signed-Nuget-Paket gefunden.
Kiryl
6

Ich bin mit einer ServiceStack-DLL darauf gestoßen, die ich mit Nuget installiert hatte. Es stellte sich heraus, dass ein weiterer Satz von DLLs verfügbar war, die als signiert gekennzeichnet waren. Dies ist nicht die Antwort für alle, aber Sie müssen möglicherweise nur nach einer vorhandenen signierten Version Ihrer Baugruppe suchen.ServiceStack.Signed

Henry Crans
quelle
2

Für mich war mein Problem, dass ich zwei gleiche NuGet-Pakete mit unterschiedlichen Versionen installiert hatte.

Demodave
quelle
2

Das Entfernen des Häkchens " Signieren der Baugruppe" unter der Registerkarte " Signieren " funktioniert wie von @Michal Stefanow angegeben.

Hier hinzufügen ist der einfachste Weg, um Ihre eigenen Dateien und / oder die Dateien anderer Personen zu signieren. Sie müssen diese Zeile nur unter der Befehlszeile "Ereignis nach dem Erstellen" hinzufügen:

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

Sie können die Dateien anderer Personen oder Ihre eigenen Dateien und beliebig viele Dateien signieren.

Geben Sie hier die Bildbeschreibung ein

Pabinator
quelle
5
Dies ist eine andere Art der Unterzeichnung. Das OP fragt, wie eine .NET-Assembly mit einem starken Namen signiert werden soll. Sie zeigen, wie Sie eine ausführbare Datei mit einem Codesignaturzertifikat signieren. Verschiedene Dinge.
Blue Toque
2

Alte Frage, aber ich bin überrascht, dass noch niemand ilmerge erwähnt hat. ilmerge stammt von Microsoft, wird jedoch nicht mit VS oder den SDKs geliefert. Sie können es jedoch hier herunterladen . Es gibt auch ein Github- Repository. Sie können auch von nuget installieren:

PM>Install-Package ilmerge

Benutzen:

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

Bei Bedarf können Sie mit sn (aus VS) Ihre eigene Schlüsseldatei generieren:

sn -k key.snk
Jahmic
quelle
1
Ich hatte das Problem mit WireMock.Net, habe es endlich zum Laufen gebracht, aber ich habe ein wenig Zeit gebraucht, um die PowerShell-Befehle herauszufinden. Insbesondere die ganze Reihe von / lib-Argumenten, um ILMerge endlich dazu zu bringen, die Assembly zu signieren.
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: Sie hatten Projekt A, B, C, D in Lösung X, Y.

Projekt A, B, C in X Projekt A, C, D in Y.

Ich brauche Projekt C in Projekt A, aber später benutze ich nicht. In bin Debug Projekt A hatte C.dll.

Wenn ich Lösung X kompiliere, ist alles gut (in dieser Lösung lösche ich Referenz A -> C.), aber in Lösung Y bekomme ich dieses Problem.

Die Lösung ist das Löschen von C.dll in Projekt A bin Debug

Martin9032
quelle
0

Stellen Sie zunächst sicher, dass alle Nuget-Pakete in allen Projekten Ihrer Lösung dieselbe Version haben. Sie möchten beispielsweise nicht, dass ein Projekt auf NLog 4.0.0.0 verweist und ein anderes Projekt auf NLog 4.1.0.0 verweist. Versuchen Sie dann, Nuget-Pakete mit neu zu installieren

Update-Paket-neu installieren

Ich hatte 3 Baugruppen von Drittanbietern, auf die von meiner Baugruppe A verwiesen wurde, und nur 2 wurden von meiner Baugruppe B in Verweise aufgenommen, die auch auf A verwiesen.

Der fehlende Verweis auf die Assembly eines Drittanbieters wurde durch den Befehl update package hinzugefügt, und der Fehler wurde behoben.

Markus
quelle