Come correggere l'errore "L'assembly di riferimento non ha un nome sicuro"?


242

Ho aggiunto un assembly con un nome debole al mio progetto Visual Studio 2005 (che è fortemente chiamato). Ora sto ricevendo l'errore:

"L'assembly di riferimento" xxxxxxxx "non ha un nome sicuro"

Devo firmare questa assemblea di terze parti?



1
Questo potrebbe sembrare un suggerimento sciocco ma se scopri che il tuo assembly non viene firmato indipendentemente da ciò che fai, controlla le impostazioni di compilazione; ricorda che VS non cancella altre architetture (qualsiasi CPU, x64, ecc.) quando ricostruisci / pulisci, quindi potresti guardare una dll obsoleta da un'altra architettura.
jrh

Risposte:


213

Per evitare questo errore è possibile:

  • Caricare il gruppo in modo dinamico oppure
  • Firma l'assemblea di terze parti.

Le istruzioni per la firma di assembly di terze parti sono disponibili in .NET-fu: Firma di un assembly non firmato (senza firma ritardata) .

Firma di assemblee di terze parti

Il principio di base per firmare una festa della sete è

  1. Disassemblare il gruppo usando ildasm.exee salvare la lingua intermedia (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Ricreare e firmare l'assembly:

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

Correzione di riferimenti aggiuntivi

I passaggi precedenti funzionano correttamente a meno che l'assembly di terzi ( A.dll ) non faccia riferimento a un'altra libreria ( B.dll ) che deve essere firmata. È possibile disassemblare, ricostruire e firmare sia A.dll che B.dll utilizzando i comandi sopra, ma in fase di esecuzione il caricamento di B.dll fallirà perché A.dll è stato originariamente creato con un riferimento alla versione non firmata di B.dll .

La soluzione a questo problema è correggere il file IL generato nel passaggio 1 sopra. Sarà necessario aggiungere il token della chiave pubblica di B.dll al riferimento. Ottieni questo token chiamando

sn -Tp B.dll 

che ti darà il seguente output:

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

L'ultima riga contiene il token della chiave pubblica. È quindi necessario cercare nell'IL di A.dll il riferimento a B.dll e aggiungere il token come segue:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}

2
Quindi firmare l'assemblaggio è un'opzione, non desidero caricare l'assemblaggio in modo dinamico né firmarlo. So che la denominazione forte riguarda la Global Assembly Cache (GAC). Nonostante, non voglio rendere i miei assiemi parte del GAC e non sono nemmeno visibili alla COM. Ricordo in parte ricordare qualcosa che potremmo fare che consentirà l'uso di questo assembly senza firmarlo. È da qualche parte nelle proprietà delle opzioni o giù di lì. Sono fuori strada e voglio andare in quel modo?
Will Marcouiller,

27
È possibile utilizzare assembly non firmati se anche il assembly è senza segno.
GU.

2
Il collegamento a .NET-fu è una risorsa fantastica
TheDude,

2
Sebbene i passaggi precedenti funzioneranno nella maggior parte delle situazioni, è incredibilmente lungo e soggetto a errori e, tra le altre cose, fallisce con i riferimenti dell'assembly degli amici. Basta usare questa utilità per fare tutto automaticamente (spudorato): stackoverflow.com/a/19459609/564726
BrutalDev

1
@Roel Ho dettagliato il processo qui delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude

98

Espandere il file di progetto che utilizza il progetto che non ha "una chiave con nome .snksicuro " e cercare il file (.StrongNameKey).

Sfoglia questo file in Esplora risorse (solo per sapere dove si trova).

Torna in Visual Studio nel progetto che non "ha una chiave con nome sicuro", fallo

  • Fare clic con il tasto destro sul file di progetto
  • Seleziona Proprietà
  • Seleziona "Scheda Firma" (a sinistra)
  • Fare clic sulla casella di controllo "Firma l'assieme"
  • Quindi <Browse>al .snkfile che hai trovato in precedenza

Questo dovrebbe fare il trucco. Ciò ha risolto un problema per me per un progetto utilizzando un modulo all'interno di un altro progetto nella stessa soluzione.

Spero possa essere d'aiuto.


Se non volessi firmare la mia assemblea non l'avrei firmata dall'inizio!
mohas,

Se non trovi il file .snk: Apri le proprietà del progetto (del progetto usando il progetto con l'errore "nome sicuro"), scheda Firma. Lì vedrai il file usato per firmare il progetto (non è sempre un file con l'estensione .snk). Copia questa impostazione sull'altro progetto.
Coder14

Come sottolineato da MrOli3000, funziona SOLO se esiste una soluzione in cui manca il file della chiave con nome sicuro. Se esistono più progetti che farebbero riferimento al progetto non firmato, è meglio creare un nuovo file chiave con nome sicuro per evitare conflitti. Nel mio caso, la soluzione non è stata sviluppata e stavo andando in cerchio cercando di risolvere. A partire da VS2017, il formato è .pfx e non .snk, ma i passaggi sono gli stessi: fai clic con il pulsante destro del mouse sulla soluzione e scegli le proprietà. Dalle schede elencate a sinistra, selezionare "Firma". Fare clic sulla casella di controllo e selezionare nuovo ... fornire un nome! e Voila! è fatto!)
Raj,

59

Stavo cercando una soluzione allo stesso problema e deselezionando l'opzione "Firma l'assemblaggio" funziona per me:

inserisci qui la descrizione dell'immagine

(come noterai lo screenshot proviene da VS2010 ma spero che possa aiutare qualcuno)


Non controllo questa impostazione nel mio progetto MVC. Ma si sta ancora lamentando di una delle dipendenze. C'è qualche altra impostazione per MVC?
Hamid Mayeli,

51

Ho scritto uno strumento per assegnare automaticamente nomi di insegne di segni, compresi quelli per i quali non si dispone del codice sorgente o di progetti che sono stati abbandonati. Utilizza molte delle tecniche descritte nelle risposte in modo semplice senza difetti o svantaggi di strumenti esistenti o istruzioni datate.

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

Spero che questo aiuti chiunque abbia bisogno di firmare un'assemblea di terze parti senza dover saltare attraverso i cerchi per arrivarci.



23

La firma dell'assemblea di terze parti ha funzionato per me:

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

EDIT : ho imparato che è utile pubblicare passaggi nel caso in cui l'articolo collegato non sia più valido. Tutto il merito va a Hiren Khirsaria :

  1. Esegui il prompt dei comandi di Visual Studio e vai alla directory in cui si trova la tua DLL.

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

  2. Ora crea il file IL usando il comando qui sotto.

    D:/hiren> ildasm /all /out=Test.il Test.dll (questo comando genera la libreria di codici)

  3. Genera nuova chiave per firmare il tuo progetto.

    D:/hiren> sn -k mykey.snk

  4. Ora firma la tua libreria usando il ilasmcomando.

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


Il tuo link ha fatto il trucco! Grazie! E spiega come creare mykey.snk (le altre risposte non dicono come)
Nicolas VERHELST,

15

Come firmare un assembly di terze parti senza segno

  1. Apri il prompt dei comandi per sviluppatori per Visual Studio. Questo strumento è disponibile nei programmi Windows e può essere trovato utilizzando la ricerca di Windows predefinita.
  2. Assicurati che il tuo prompt abbia accesso ai seguenti strumenti eseguendoli una volta: sn ildasmeilasm
  3. Passare alla cartella in cui si trova Cool.Library.dll
  4. sn –k Cool.Library.snk per creare una nuova coppia di chiavi
  5. ildasm Cool.Library.dll /out:Cool.Library.il per smontare la biblioteca
  6. move Cool.Library.dll Cool.Library.unsigned.dll per mantenere la libreria originale come backup
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk per riassemblare la biblioteca con un nome sicuro
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"per ottenere il nome completo dell'assembly. Sarà necessario questo bit se si deve fare riferimento alla DLL in file di configurazione esterni come web.config o app.config.

6

Ho riscontrato questo problema per un'app che aveva un nome sicuro, quindi ho dovuto cambiarlo per fare riferimento a un assembly con un nome non forte, quindi ho deselezionato "Firma l'assembly" nella sezione Firma delle proprietà del progetto ma mi sono comunque lamentato. Ho pensato che dovesse essere un artefatto da qualche parte a causare il problema dato che ho fatto tutto il resto correttamente ed era proprio quello. Ho trovato e rimosso la riga: [assembly: AssemblyKeyFile ("yourkeyfilename.snk")] dal suo file assemblyInfo.cs. Quindi nessun reclamo in seguito.


Grazie! Grazie alla tua risposta, lo ricontrollo per il mio problema (ClosedXML) e ho trovato anche il pacchetto nuget ClosedXML.Signed.
Kiryl,

6

Mi stavo imbattendo in questo con una dll ServiceStack che avevo installato con nuget. Si scopre che c'era un altro set di dll disponibili che erano etichettati firmati. Non sarà la risposta per tutti, ma potrebbe essere necessario verificare la presenza di una versione firmata esistente dell'assembly.ServiceStack.Signed


2

Per me il mio problema era che avevo due degli stessi pacchetti NuGet installati con versioni diverse.


2

Rimozione del segno di spunta "Firma l'assieme" sotto "Firma" scheda funziona come ha detto @Michal Stefanow.

Aggiungi qui è il modo più semplice per firmare i tuoi file e / o i file di altre persone. Devi solo aggiungere questa riga nella "Riga di comando dell'evento 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)"

Puoi firmare i file di altre persone o i tuoi file e quanti ne vuoi.

inserisci qui la descrizione dell'immagine


5
Questo è un diverso tipo di firma. Ciò che l'OP chiede è come firmare un assembly .NET con un nome sicuro. Stai mostrando come firmare un eseguibile con un certificato di firma del codice. Cose differenti.
Blue Toque,

2

Vecchia domanda, ma sono sorpreso che nessuno abbia ancora menzionato ilmerge. ilmerge proviene da Microsoft, ma non viene fornito con VS o SDK. Puoi scaricarlo da qui però. C'è anche un repository github . Puoi anche installare da nuget:

PM>Install-Package ilmerge

Usare:

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

Se necessario, puoi generare il tuo file di chiavi usando sn (da VS):

sn -k key.snk

1
Ho avuto il problema con WireMock.Net, finalmente ho funzionato, ma mi ci è voluto un po 'di tempo per capire i comandi di PowerShell. In particolare l'intero gruppo di argomenti / lib per ottenere finalmente ILMerge per firmare 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

Situazione: avevi il progetto A, B, C, D nella soluzione X, Y

Progetto A, B, C in X Progetto A, C, D in Y

Ho bisogno di usare il progetto C nel progetto A, ma in seguito non lo uso. Nel bin Il progetto di debug A aveva C.dll.

Se compilo la soluzione X, tutto bene (in questa soluzione elimino il riferimento A -> C.), ma nella soluzione Y ottengo questo problema.

La soluzione è eliminare C.dll nel progetto A bin Debug


0

Per prima cosa assicurati che tutti i pacchetti nuget siano nella stessa versione per tutti i progetti nella tua soluzione. ad esempio, non si desidera che un progetto faccia riferimento a NLog 4.0.0.0 e un altro progetto faccia riferimento a NLog 4.1.0.0. Quindi prova a reinstallare i pacchetti nuget con

Update-Package -reinstall

Avevo 3 assiemi di terze parti a cui faceva riferimento il mio assemblaggio A e solo 2 erano inclusi in Riferimenti dal mio assemblaggio B che faceva anche riferimento a A.

Il riferimento mancante all'assembly di terze parti è stato aggiunto dal comando del pacchetto di aggiornamento e l'errore è scomparso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.