Как исправить ошибку «Ссылочная сборка не имеет строгого имени»?

242

Я добавил сборку со слабым именем в мой проект Visual Studio 2005 (который строго назван). Теперь я получаю сообщение об ошибке:

«Ссылочная сборка« xxxxxxxx »не имеет строгого имени»

Нужно ли подписывать эту стороннюю сборку?

ng5000
источник
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файл, который вы нашли ранее

Это должно делать свое дело. Это решило проблему для меня для одного проекта, используя форму внутри другого проекта в том же решении.

Я надеюсь, что это помогает.

MrOli3000
источник
Если бы я не хотел подписывать свою сборку, я бы не подписал ее с самого начала!
Мохас
Если вы не нашли .snk-файл: откройте свойства проекта (проекта, использующего проект с ошибкой «строгое имя»), вкладка «Подписание». Там вы увидите файл, используемый для подписи проекта (это не всегда файл с расширением .snk). Просто скопируйте этот параметр в другой проект.
Coder14
Как указывает MrOli3000, он работает ТОЛЬКО, если есть одно решение, в котором отсутствует файл ключа строгого имени. Если существует несколько проектов, которые ссылаются на неподписанный проект, лучше создать новый файл ключа строгого имени, чтобы избежать конфликтов. В моем случае решение не строилось, и я собирался по кругу, пытаясь исправить. Начиная с VS2017, формат .pfx, а не .snk, но шаги одинаковые - щелкните правой кнопкой мыши на решении и выберите свойства. На вкладках, перечисленных слева, выберите «Подписание». Установите флажок и выберите новый ... укажите имя! и вуаля! это сделано!)
Радж
59

Я искал решение той же проблемы, и снятие галочки с опции «Подписать сборку» работает для меня:

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

(как вы можете заметить, скриншот взят с VS2010, но, надеюсь, он кому-нибудь поможет)

Марс Робертсон
источник
Я не проверяю этот параметр в своем проекте MVC. Но он все еще жалуется на одну из зависимостей. Есть ли другие настройки для MVC?
Хамид Майели
51

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

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

Надеюсь, что это поможет всем, кому нужно подписать стороннюю сборку, не прыгая через обручи, чтобы добраться туда.

BrutalDev
источник
40

Вы можете использовать неподписанные сборки, если ваша сборка также не подписана.

Александр никитин
источник
23

Подписание сторонней сборки у меня сработало:

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

РЕДАКТИРОВАТЬ : я узнал, что полезно опубликовать шаги в случае, если связанная статья больше не действительна. Вся заслуга Hiren Khirsaria :

  1. Запустите командную строку visual studio и перейдите в каталог, где находится ваша 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

mateuscb
источник
Ваша ссылка сделала свое дело! Спасибо! И это объясняет, как создать mykey.snk (другие ответы не говорят как)
Николас ФЕРХЕЛЬСТ
15

Как подписать стороннюю сборку без подписи

  1. Откройте командную строку разработчика для Visual Studio. Этот инструмент доступен в ваших программах Windows и может быть найден с помощью поиска 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) и также обнаружил пакет nuget ClosedXML.Signed.
Кирилл
6

Я столкнулся с этим с DLL ServiceStack, которую я установил с Nuget. Оказывается, был еще один набор доступных библиотек, которые были помечены как подписанные. Не будет ответом для всех, но вам, возможно, просто нужно проверить существующую подписанную версию вашей сборки.ServiceStack.Signed

Генри Кранс
источник
2

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

Demodave
источник
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)"

Вы можете подписывать файлы других людей или свои собственные файлы и столько, сколько хотите.

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

Pabinator
источник
5
Это другой вид подписания. ОП спрашивает, как подписать сборку .NET строгим именем. Вы показываете, как подписать исполняемый файл сертификатом подписи кода. Разные вещи.
Blue Toque
2

Старый вопрос, но я удивлен, что еще никто не упомянул ilmerge. 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
Jahmic
источник
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 A был C.dll.

Если я компилирую решение X, все хорошо (в этом решении я удаляю ссылку A -> C.), но в решении Y я получаю эту проблему.

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

Martin9032
источник
0

Сначала убедитесь, что все пакеты nuget имеют одинаковую версию для всех проектов в вашем решении. Например, вы не хотите, чтобы один проект ссылался на NLog 4.0.0.0, а другой - на NLog 4.1.0.0. Затем попробуйте переустановить пакеты nuget с

Update-Package -reinstall

У меня было 3 сторонних сборки, на которые ссылалась моя сборка А, и только 2 были включены в Ссылки моей сборкой Б, которая также ссылалась на А.

Отсутствующая ссылка на стороннюю сборку была добавлена ​​командой пакета обновления, и ошибка исчезла.

Markus
источник