Bagaimana cara memperbaiki kesalahan "Majelis yang dirujuk tidak memiliki nama yang kuat"?

242

Saya telah menambahkan perakitan dengan nama lemah ke proyek Visual Studio 2005 saya (yang sangat dinamai). Saya sekarang mendapatkan kesalahan:

"Perakitan yang direferensikan 'xxxxxxxx' tidak memiliki nama yang kuat"

Apakah saya perlu menandatangani majelis pihak ketiga ini?

ng5000
sumber
1
Ini mungkin terdengar seperti tip konyol tetapi jika Anda menemukan bahwa perakitan Anda tidak ditandatangani apa pun yang Anda lakukan, periksa pengaturan build Anda; ingat bahwa VS tidak menghapus arsitektur lain (CPU apa pun, x64, dll) ketika Anda membangun kembali / bersih, sehingga Anda bisa melihat dll yang usang dari arsitektur lain.
jrh

Jawaban:

213

Untuk menghindari kesalahan ini, Anda dapat:

  • Muat unit secara dinamis, atau
  • Tanda tangani majelis pihak ketiga.

Anda akan menemukan petunjuk tentang cara menandatangani majelis pihak ketiga di .NET-fu: Menandatangani Majelis yang Tidak Ditandatangani (Tanpa Penandatanganan Penundaan) .

Menandatangani Majelis Pihak Ketiga

Prinsip dasar untuk menandatangani pihak ketiga adalah untuk

  1. Bongkar perakitan menggunakan ildasm.exedan menyimpan bahasa perantara (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Bangun kembali dan tandatangani majelis:

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

Memperbaiki Referensi Tambahan

Langkah-langkah di atas berfungsi dengan baik kecuali jika perakitan pihak ketiga Anda ( A.dll ) referensi perpustakaan lain ( B.dll ) yang juga harus ditandatangani. Anda dapat membongkar, membangun kembali dan menandatangani kedua A.dll dan B.dll menggunakan perintah di atas, tetapi pada saat runtime, pemuatan B.dll akan gagal karena A.dll awalnya dibangun dengan mengacu pada unsigned versi B.dll .

Perbaikan untuk masalah ini adalah untuk menambal file IL yang dihasilkan pada langkah 1 di atas. Anda perlu menambahkan token kunci publik B.dll ke referensi. Anda mendapatkan token ini dengan menelepon

sn -Tp B.dll 

yang akan memberi Anda output berikut:

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

Baris terakhir berisi token kunci publik. Anda kemudian harus mencari IL dari A.dll untuk referensi ke B.dll dan menambahkan token sebagai berikut:

.assembly extern /*23000003*/ MyAssemblyName
{
  .publickeytoken = (A8 A7 ED 72 03 D8 7B C9 )                         
  .ver 10:0:0:0
}
Dirk Vollmar
sumber
2
Jadi menandatangani opsi perakitan, saya tidak ingin memuat perakitan secara dinamis atau untuk menandatanganinya. Saya tahu bahwa penamaan yang kuat terkait dengan Global Assembly Cache (GAC). Meskipun demikian, saya tidak ingin membuat majelis saya menjadi bagian dari GAC dan keduanya juga tidak terlihat COM. Saya ingat sebagian mengingat sesuatu yang mungkin kami lakukan yang akan memungkinkan penggunaan majelis ini tanpa menandatanganinya. Itu di suatu tempat di properti opsi atau lebih. Apakah saya keluar jalur ingin pergi ke sana?
Will Marcouiller
27
Anda dapat menggunakan rakitan yang tidak ditandatangani jika rakitan Anda juga yang tidak ditandatangani.
OJ.
2
Tautan ke .NET-fu adalah sumber yang luar biasa
TheDude
2
Meskipun langkah-langkah di atas akan bekerja dalam situasi "kebanyakan", itu sangat memakan waktu dan rawan kesalahan dan gagal dengan referensi perakitan teman antara lain. Cukup gunakan utilitas ini untuk melakukan semuanya secara otomatis (plug shameless): stackoverflow.com/a/19459609/564726
BrutalDev
1
@Roel Saya telah merinci prosesnya di sini delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude
98

Perluas file proyek yang menggunakan proyek yang tidak "memiliki kunci nama yang kuat" dan cari .snkfile (.StrongNameKey).

Jelajahi file ini di Windows Explorer (hanya agar Anda tahu di mana itu).

Kembali di Visual Studio dalam proyek yang tidak "memiliki kunci nama yang kuat", lakukan

  • Klik kanan pada file proyek
  • Pilih Properties
  • Pilih "Tab Penandatanganan" (di sebelah kiri)
  • Klik kotak centang "Masuk majelis"
  • Kemudian <Browse>ke .snkfile yang Anda temukan sebelumnya

Itu harus melakukan trik. Ini memecahkan masalah bagi saya untuk satu proyek menggunakan formulir di dalam proyek lain dalam solusi yang sama.

Saya harap ini membantu.

MrOli3000
sumber
Jika saya tidak ingin menandatangani majelis saya, saya tidak akan menandatanganinya sejak awal!
mohas
Jika Anda tidak menemukan file .snk: Buka properti proyek (dari proyek yang menggunakan proyek dengan kesalahan "nama kuat"), tab Signing. Di sana Anda akan melihat file yang digunakan untuk menandatangani proyek (tidak selalu file dengan ekstensi .snk). Cukup salin pengaturan ini ke proyek lain.
Coder14
Seperti yang ditunjukkan oleh MrOli3000, HANYA berfungsi jika ada satu solusi yang kehilangan file kunci nama yang kuat. Jika ada beberapa proyek yang akan referensi proyek yang tidak ditandatangani, Anda lebih baik membuat file kunci nama kuat baru untuk menghindari konflik. Dalam kasus saya, solusinya tidak membangun, dan saya berputar-putar mencoba untuk memperbaikinya. Pada VS2017, formatnya adalah .pfx dan bukan .snk, tetapi langkah-langkahnya sama - Klik kanan pada solusi dan pilih properti. Dari tab yang tercantum di sebelah kiri, pilih "Signing". Klik kotak centang dan pilih baru ... berikan nama! dan Voila! itu selesai!)
Raj
59

Saya sedang mencari solusi untuk masalah yang sama dan tidak mencentang opsi "Masuk majelis" berfungsi untuk saya:

masukkan deskripsi gambar di sini

(karena Anda mungkin melihat tangkapan layar berasal dari VS2010 tetapi mudah-mudahan itu akan membantu seseorang)

Mars Robertson
sumber
Saya tidak memeriksa pengaturan ini di proyek MVC saya. Tetapi masih mengeluh tentang salah satu dependensi. Apakah ada pengaturan lain untuk MVC?
Hamid Mayeli
51

Saya telah menulis sebuah alat untuk secara otomatis nama majelis tanda yang kuat termasuk yang Anda tidak memiliki kode sumber untuk atau proyek yang telah ditinggalkan. Ini menggunakan banyak teknik yang dijelaskan dalam jawaban dengan cara yang sederhana tanpa kekurangan atau kekurangan alat yang ada atau instruksi tanggal.

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

Semoga ini bisa membantu siapa saja yang perlu menandatangani majelis pihak ketiga tanpa harus melewati rintangan untuk sampai ke sana.

BrutalDev
sumber
40

Anda dapat menggunakan rakitan yang tidak ditandatangani jika rakitan Anda juga yang tidak ditandatangani.

Alexandr Nikitin
sumber
23

Menandatangani majelis pihak ketiga berhasil untuk saya:

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

EDIT : Saya telah mempelajari bahwa sangat membantu untuk memposting langkah-langkah seandainya artikel yang ditautkan tidak lagi valid. Semua kredit diberikan kepada Hiren Khirsaria :

  1. Jalankan perintah visual studio prompt dan buka direktori tempat DLL Anda berada.

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

  2. Sekarang buat file IL menggunakan perintah di bawah ini.

    D:/hiren> ildasm /all /out=Test.il Test.dll (perintah ini menghasilkan pustaka kode)

  3. Hasilkan kunci baru untuk menandatangani proyek Anda.

    D:/hiren> sn -k mykey.snk

  4. Sekarang tandatangani perpustakaan Anda menggunakan ilasmperintah.

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

mateuscb
sumber
Tautan Anda berhasil! Dan ini menjelaskan cara membuat mykey.snk (jawaban lain mereka tidak mengatakan bagaimana)
Nicolas VERHELST
15

Cara menandatangani majelis pihak ketiga yang tidak ditandatangani

  1. Buka Prompt Perintah Pengembang untuk Visual Studio. Alat ini tersedia di program Window Anda dan dapat ditemukan menggunakan pencarian Windows default.
  2. Pastikan prompt Anda memiliki akses ke alat-alat berikut dengan menjalankannya sekali: sn ildasmdanilasm
  3. Arahkan ke folder tempat Cool.Library.dll Anda berada
  4. sn –k Cool.Library.snk untuk membuat pasangan kunci baru
  5. ildasm Cool.Library.dll /out:Cool.Library.il untuk membongkar perpustakaan
  6. move Cool.Library.dll Cool.Library.unsigned.dll untuk menyimpan perpustakaan asli sebagai cadangan
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk untuk merakit kembali perpustakaan dengan nama yang kuat
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"untuk mendapatkan nama majelis sepenuhnya memenuhi syarat. Anda akan memerlukan bit ini jika Anda harus merujuk DLL dalam file konfigurasi eksternal seperti web.config atau app.config.
Martin Devillers
sumber
6

Saya memiliki masalah ini untuk aplikasi yang sangat bernama kemudian harus mengubahnya untuk referensi perakitan yang tidak bernama, jadi saya hapus centang 'Masuk perakitan' di bagian Penandatanganan properti proyek tetapi masih mengeluh. Saya pikir itu harus menjadi artefak di suatu tempat yang menyebabkan masalah karena saya melakukan segalanya dengan benar dan hanya itu. Saya menemukan dan menghapus baris: [assembly: AssemblyKeyFile ("yourkeyfilename.snk")] dari file assemblyInfo.cs. Maka tidak ada keluhan membangun setelah itu.

Joe
sumber
Terima kasih! Karena jawaban Anda, saya periksa kembali untuk masalah saya (ClosedXML) dan menemukan paket nuget ClosedXML.
Kiryl
6

Saya mengalami ini dengan ServiceStack dll saya telah menginstal dengan nuget. Ternyata ada satu set dll yang tersedia yang diberi label ditandatangani. Tidak akan menjadi jawaban untuk semua orang, tetapi Anda mungkin hanya perlu memeriksa versi rakitan Anda yang sudah ditandatangani.ServiceStack. Ditandatangani

Henry Crans
sumber
2

Bagi saya masalah saya adalah saya memiliki dua Paket NuGet yang sama diinstal dengan Versi yang berbeda.

Demodave
sumber
2

Menghapus tanda centang "Masuk unit" di bawah "Penandatanganan" tab berfungsi seperti yang dikatakan @Michal Stefanow.

Tambahkan di sini adalah cara paling sederhana untuk menandatangani file Anda sendiri dan / atau file orang lain. Anda hanya perlu menambahkan baris ini di bawah "Baris perintah acara 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)"

Anda dapat menandatangani file orang lain atau file Anda sendiri dan sebanyak yang Anda inginkan.

masukkan deskripsi gambar di sini

Pabinator
sumber
5
Ini adalah jenis penandatanganan yang berbeda. Yang ditanyakan OP adalah bagaimana cara menandatangani .NET assembly dengan nama yang kuat. Anda menunjukkan cara menandatangani executable dengan sertifikat penandatanganan kode. Hal yang berbeda.
Blue Toque
2

Pertanyaan lama, tapi saya terkejut belum ada yang menyebutkan ilmerge. ilmerge berasal dari Microsoft, tetapi tidak dikirimkan bersama VS atau SDK. Anda dapat mengunduhnya dari sini . Ada juga repositori github . Anda juga dapat menginstal dari nuget:

PM>Install-Package ilmerge

Menggunakan:

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

Jika perlu, Anda dapat membuat keyfile Anda sendiri menggunakan sn (dari VS):

sn -k key.snk
Jahmic
sumber
1
Saya punya masalah dengan WireMock.Net, akhirnya berhasil, tetapi butuh sedikit waktu untuk mencari tahu perintah PowerShell. Khususnya sejumlah argumen / lib untuk akhirnya membuat ILMerge menandatangani majelis.
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

Situasi: Anda memiliki proyek A, B, C, D dalam solusi X, Y

Proyek A, B, C dalam X Proyek A, C, D dalam Y

Saya perlu menggunakan proyek C di proyek A, tetapi nanti saya tidak menggunakannya. Dalam proyek bin Debug A memiliki C.dll.

Jika saya mengkompilasi solusi X, semuanya baik (dalam solusi ini saya menghapus referensi A -> C.), tetapi dalam solusi YI mendapatkan masalah ini.

Solusi adalah hapus C.dll dalam proyek A bin Debug

Martin9032
sumber
0

Pertama-tama pastikan semua paket nuget berada pada versi yang sama di semua proyek dalam solusi Anda. mis. Anda tidak ingin satu proyek untuk referensi NLog 4.0.0.0 dan proyek lain untuk referensi NLog 4.1.0.0. Kemudian coba instal ulang paket nuget dengan

Update-Package -reinstall

Saya memiliki 3 majelis pihak ke-3 yang dirujuk oleh majelis A saya dan hanya 2 yang dimasukkan dalam Referensi oleh majelis B saya yang juga dirujuk A.

Referensi yang hilang untuk perakitan pihak ke-3 ditambahkan oleh perintah paket pembaruan, dan kesalahan hilang.

Markus
sumber