Як виправити помилку "Посилання на збірку не має сильного імені"?


242

Я додав слабко названу збірку до свого проекту Visual Studio 2005 (який названий настійно). Зараз я отримую помилку:

"Посилана збірка" xxxxxxxx "не має сильної назви"

Чи потрібно підписувати цю сторонні збори?



1
Це може здатися нерозумною підказкою, але якщо ви виявите, що ваша збірка не підписується незалежно від того, що ви робите, перевірте свої настройки збірки; пам’ятайте, що VS не очищає інших архітектур (будь-який процесор, x64 тощо), коли ви відновлюєте / очищаєте, тож ви можете переглядати застарілий dll з іншої архітектури.
jrh

Відповіді:


213

Щоб уникнути цієї помилки, ви можете:

  • Завантажте збірку динамічно, або
  • Підпишіть сторонні збори.

Ви знайдете інструкції щодо підписання сторонніх зборів у .NET-fu: Підписання безпідписаної асамблеї (без затримки підпису) .

Підписання сторонніх зборів

Основний принцип підписання третьої сторони - це

  1. Розбирайте збірку, використовуючи ildasm.exeта зберігаючи проміжну мову (IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
  2. Перебудуйте та підпишіть збірку:

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

Виправлення додаткових посилань

Наведені вище кроки працюють добре, якщо ваша стороння збірка ( A.dll ) не посилається на іншу бібліотеку ( B.dll ), яку також потрібно підписати. Ви можете розібрати, відновити та підписати як A.dll, так і B.dll, використовуючи команди вище, але під час виконання завантаження B.dll не вдасться, тому що A.dll спочатку був побудований з посиланням на непідписану версію B.dll .

Виправлення цієї проблеми полягає в виправлення файлу IL, згенерованого на кроці 1 вище. Вам потрібно буде додати маркер B.dll відкритого ключа до посилання. Ви отримуєте цей маркер, зателефонувавши

sn -Tp B.dll 

який дасть вам такий вихід:

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

Останній рядок містить маркер відкритого ключа. Тоді вам доведеться шукати IL з A.dll для посилання на B.dll і додати маркер так:

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

2
Таким чином, підписування збірки є опцією, я ні хочу динамічно завантажувати збірку, ні підписувати її. Я знаю, що чітке називання стосується кеша глобальної асамблеї (GAC). Незважаючи на те, я не хочу робити свої збори частиною GAC, і вони не є видимими для COM. Я частково пам'ятаю, що ми можемо зробити, що дозволить використовувати цю збірку без її підписання. Це десь у властивостях опцій чи так. Невже я не хочу ходити таким шляхом?
Буде Маркуйлер

27
Ви можете використовувати безпідписані збірки, якщо ваша збірка також не підписана.
ОВ.

2
Посилання на .NET-fu - дивовижний ресурс
TheDude

2
Хоча вищезазначені кроки працюватимуть у "більшості" ситуацій, це надзвичайно багато часу та схильність до помилок, а також серед інших посилань не вдається. Просто використовуйте цю утиліту , щоб зробити все це автоматично (безсоромний штепсель): stackoverflow.com/a/19459609/564726
BrutalDev

1
@Roel Я детально описав процес delabs.io/the-12th-labor-of-a-net-developer-part-4
TheDude

98

Розгорніть файл проекту, який використовує проект, у якого немає "сильної клавіші імені", і знайдіть .snkфайл (.StrongNameKey).

Перегляньте цей файл у Провіднику Windows (просто щоб ви знали, де він знаходиться).

Поверніться до Visual Studio в проекті, що не має "сильної клавіші імені"

  • Клацніть правою кнопкою миші на файл проекту
  • Виберіть Властивості
  • Виберіть "Вкладка підписання" (зліва)
  • Установіть прапорець "Підписати збірку"
  • Потім <Browse>до .snkфайлу, який ви знайшли раніше

Це повинно зробити трюк. Це вирішило для мене проблему для одного проекту, використовуючи форму всередині іншого проекту в тому самому рішенні.

Я сподіваюся, що це допомагає.


Якби я не хотів підписувати свою асамблею, я б не підписав її з самого початку!
mohas

Якщо ви не знайдете .snk-файл: Відкрийте властивості проекту (проекту, використовуючи проект із помилкою "сильне ім'я"), вкладку Підписання. Там ви побачите файл, який використовується для підписання проекту (не завжди це файл із розширенням .snk). Просто скопіюйте це налаштування в інший проект.
Coder14

Як вказує MrOli3000, він працює ТІЛЬКИ, якщо є одне рішення, у якому відсутній файл із ключовим ім'ям сильного імені. Якщо існує кілька проектів, які б посилалися на безпідписаний проект, вам краще створити новий файл ключових імен, щоб уникнути конфліктів. У моєму випадку рішення не склалося, і я збирався по колах, намагаючись виправити. Станом на VS2017 формат .pfx, а не .snk, але кроки однакові - Клацніть правою кнопкою миші рішення та виберіть властивості. На вкладках ліворуч виберіть "Підпис". Установіть прапорець і встановіть нове ... вкажіть ім’я! і Вуаля! це зроблено!)
Радж

59

Я шукав рішення тієї самої проблеми і відміняв позначку "Підписати збірку" для мене працює:

введіть тут опис зображення

(як ви можете помітити, скріншот походить від VS2010, але, сподіваємось, це комусь допоможе)


Я не перевіряю цей параметр у своєму проекті MVC. Але все одно скаржиться на одну із залежностей. Чи є якісь інші налаштування для MVC?
Хамід Майелі

51

Я написав інструмент для автоматичних збірок знакових імен, включаючи ті, для яких у вас немає вихідного коду, або проекти, які були відмовлені. Він використовує багато методів, описаних у відповідях простим способом, без будь-яких недоліків чи недоліків існуючих інструментів чи датованих інструкцій.

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

Сподіваємось, це допоможе кожному, кому потрібно підписати сторонні збори, не потрібно стрибати через обручі, щоб потрапити туди.



23

Підписання сторонньої асамблеї працювало на мене:

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

EDIT : Я дізнався, що корисно розміщувати кроки у випадку, якщо пов’язана стаття більше не діє. Усі кредити належать Хірен Хірсарія :

  1. Запустіть командний рядок візуальної студії та перейдіть до каталогу, де знаходиться ваша DLL.

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

  2. Тепер створіть файл IL за допомогою команди нижче.

    D:/hiren> ildasm /all /out=Test.il Test.dll (ця команда створює бібліотеку коду)

  3. Створіть новий ключ для підписання свого проекту.

    D:/hiren> sn -k mykey.snk

  4. Тепер підпишіть свою бібліотеку за допомогою ilasmкоманди.

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


Ваше посилання зробило трюк! Дякую! І це пояснює, як створити mykey.snk (вони інші відповіді не говорять як)
Ніколас ВЕРХЕЛЬСТ

15

Як підписати сторонні збори без підпису

  1. Відкрийте командний рядок розробника для Visual Studio. Цей інструмент доступний у ваших програмах Window і його можна знайти за допомогою пошуку в Windows за замовчуванням.
  2. Переконайтеся, що ваш підказник має доступ до таких інструментів, виконавши їх один раз: sn ildasmіilasm
  3. Перейдіть до папки, де знаходиться ваш Cool.Library.dll
  4. sn –k Cool.Library.snk щоб створити нову пару ключів
  5. ildasm Cool.Library.dll /out:Cool.Library.il розібрати бібліотеку
  6. move Cool.Library.dll Cool.Library.unsigned.dll щоб зберегти оригінальну бібліотеку як резервну копію
  7. ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk зібрати бібліотеку із сильною назвою
  8. powershell -command "& {[System.Reflection.AssemblyName]::GetAssemblyName($args).FullName} Cool.Library.dll"щоб отримати повне кваліфіковану назву збірки. Цей біт вам знадобиться, якщо вам доведеться посилатися на DLL у зовнішніх файлах конфігурації, таких як web.config або app.config.

6

У мене виникла ця проблема для додатка, який отримав чітке ім'я, тоді довелося змінити його, щоб посилатися на збірку, що не має найменування, тому я зняв прапорець "Підписати збірку" у розділі "Підписання властивостей проекту", але він все ще скаржився. Я подумав, що це повинен бути артефакт десь причиною проблеми, оскільки я все інше зробив правильно, і це було саме так. Я знайшов і вилучив рядок: [Assembly: AssemblyKeyFile ("yourkeyfilename.snk")] з його файлу AssemblyInfo.cs. Тоді не будуйте скарг після цього.


Дякую! Через вашу відповідь я повторно перевіряю його на свою проблему (ClosedXML) і знайшов пакет ClosedXML.Signed nuget.
Кирил

6

Я зіткнувся з цим з DLL ServiceStack, який я встановив з nuget. Виявляється, був ще один набір коктейлів, які були підписані підписом. Це не буде відповіддю для всіх, але вам може знадобитися лише перевірити наявність наявної підписаної версії вашої збірки.ServiceStack.Signed


2

Для мене моєю проблемою було те, що у мене було встановлено два однакових пакети NuGet з різними версіями.


2

Зняття галочки "Підписати збірку" на вкладці "Підписання" працює так, як сказав @Michal Stefanow.

Додайте сюди найпростіший спосіб підписати власні файли та / або файли інших людей. Вам просто потрібно додати цей рядок у "Командний рядок події після складання":

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

Ви можете підписувати чужі файли чи власні файли та скільки завгодно.

введіть тут опис зображення


5
Це різного роду підписи. ОП запитує, як підписати .NET-збірку із сильною назвою. Ви показуєте, як підписати виконуваний файл із сертифікатом підпису коду. Різні речі.
Блакитний Ток

2

Старе питання, але я здивований, що ще ніхто не згадав ілмерге. ilmerge - від Microsoft, але не постачається разом з VS або SDK. Ви можете завантажити його звідси . Також є сховище github . Ви також можете встановити з nuget:

PM>Install-Package ilmerge

Використовувати:

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

Якщо потрібно, ви можете створити власний файл ключів за допомогою sn (від VS):

sn -k key.snk

1
У мене виникла проблема з WireMock.Net, нарешті, він спрацював, але мені знадобилося трохи часу, щоб розібратися в командах PowerShell. Особливо ціла купа аргументів / lib, щоб нарешті отримати ILMerge для підписання асамблеї.
Франсуа

1> Register-PackageSource -ProviderName NuGet -Name NuGet -Location http://www.nuget.org/api/v2
Франсуа

2> Install-Package -Name ILMerge
Франсуа

3> $env:path += ';C:\Program Files\PackageManagement\NuGet\Packages\ilmerge.2.14.1208\tools'
Франсуа

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
Франсуа

1

Ситуація: у вас був проект A, B, C, D у розчині X, Y

Проект A, B, C у X Проект A, C, D у Y

Мені потрібно використовувати проект C в проекті A, але пізніше я не використовую. У bin Debug проекту A був C.dll.

Якщо я компілюю рішення X, все добре (в цьому рішенні я видаляю посилання A -> C.), але у рішенні YI я отримую цю проблему.

Рішення - видалити C.dll у проекті A bin Debug


0

Спершу переконайтесь, що всі пакунки з цілими файлами мають однакову версію для всіх проектів у вашому рішенні. наприклад, ви не хочете, щоб один проект посилався на NLog 4.0.0.0, а інший - на NLog 4.1.0.0. Потім спробуйте перевстановити пакунки з нуля

Update-Package -перевстановити

У мене було 3 сторонні збори, на які посилалася моя асамблея А, і лише 2 були включені до Посилань моєї асамблеї Б, на які також посилався А.

Відсутня посилання на сторонні збори була додана командою пакету оновлення, і помилка усунулася.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.