如何解决“参考程序集没有强名称”错误?


241

我已经在我的Visual Studio 2005项目(即强命名)中添加了一个弱命名的程序集。我现在收到错误:

“引用的程序集“ xxxxxxxx”没有强名称”

我是否需要签署此第三方程序集?



1
这听起来像是一个愚蠢的提示,但是如果您发现程序集无论如何都未得到签名,请检查构建设置;否则,请执行以下步骤。请记住,VS在重建/清理时不会清除其他体系结构(任何CPU,x64等),因此您可能正在查看另一种体系结构中过时的dll。
jrh

Answers:


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.DLLB.DLL使用上面的命令,但在运行时,装载B.DLL将失败,因为A.DLL最初是在参考内置未签名的版本B.DLL

解决此问题的方法是修补上述步骤1中生成的IL文件。您将需要将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

最后一行包含公钥令牌。然后,您必须在A.dll的IL中搜索对B.dll的引用,并按如下所示添加令牌:

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

2
因此,对程序集进行签名是一种选择,我既不希望动态加载程序集也不对其进行签名。我知道,对于全局程序集缓存(GAC)而言,命名很严格。尽管如此,我不想使我的程序集成为GAC的一部分,它们也不是COM可见的。我记得部分记得我们可能会做的事情,这将允许使用该程序集而无需对其进行签名。它位于options属性左右。我想走那条路吗?
Will Marcouiller 09年

27
如果程序集也是未签名的,则可以使用未签名的程序集。
OJ。

2
到.NET-fu的链接是一个了不起的资源
TheDude15年

2
尽管以上步骤在“大多数”情况下都可以使用,但它非常耗时且容易出错,并且在其他情况下无法通过好友程序集引用进行操作。只需使用此实用程序即可自动完成所有操作(无耻的插件):stackoverflow.com/a/19459609/564726
BrutalDev

1
@Roel我在这里详细介绍了此过程delabs.io/the-12th-labor-of-net-developer-part-4
TheDude

98

展开使用没有“具有强名称键”的项目的项目文件,然后查找.snk文件(.StrongNameKey)。

Windows资源管理器中浏览至该文件(只是为了知道它在哪里)。

回到项目“没有强名称键”的Visual Studio中,执行

  • 右键单击项目文件
  • 选择属性
  • 选择“签名”标签(在左侧)
  • 单击复选框“签署程序集”
  • 然后<Browse>.snk您之前找到的文件

这应该够了吧。这为我解决了一个项目的问题,该项目在同一解决方案中的另一个项目中使用了表单。

希望对您有所帮助。


如果我不想对程序集进行签名,那么就不会从一开始就对它进行签名!
mohas 2014年

如果找不到.snk文件:打开项目属性(使用带有“强名称”错误的项目的项目属性),然后单击“签名”。在那里,您将看到用于签署项目的文件(并不总是带有.snk扩展名的文件)。只需将此设置复制到另一个项目。
Coder14 2015年

正如MrOli3000所指出的,只有在缺少强名称密钥文件的一种解决方案的情况下,它才有效。如果存在多个引用未签名项目的项目,则最好创建一个新的强名称密钥文件,以避免任何冲突。就我而言,该解决方案未构建,我正围着圈子试图解决。从VS2017开始,格式为.pfx而非.snk,但步骤相同-右键单击解决方案并选择属性。从左侧列出的选项卡中,选择“签名”。单击复选框,然后选择新建...提供名称!和瞧!它完成了!)
Raj

58

我一直在寻找解决同一问题的方法,因此取消勾选“签署程序集”选项对我有用:

在此处输入图片说明

(您可能会注意到屏幕截图来自VS2010,但希望能对您有所帮助)


我不在我的MVC项目中检查此设置。但是它仍然在抱怨依赖项之一。MVC还有其他设置吗?
Hamid Mayeli



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


您的链接成功了!谢谢!它解释了如何创建mykey.snk(其他答案没有说明如何)
Nicolas VERHELST

15

如何签署未签名的第三方程序集

  1. 打开Visual Studio的开发人员命令提示符。该工具在您的Window程序中可用,并且可以使用默认的Windows搜索找到。
  2. 通过一次执行,确保您的提示可以访问以下工具:sn ildasmilasm
  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"获得程序集的完全合格名称。如果必须在外部配置文件(例如web.config或app.config)中引用DLL,则需要此位。

6

我遇到了一个应用程序的问题,该应用程序被强命名,然后必须对其进行更改以引用一个名称不强的程序集,因此我在项目属性的“签名”部分中未选中“对程序集进行签名”,但仍存在问题。我认为这一定是导致问题的伪影,因为我正确地完成了所有其他操作,仅此而已。我发现并从其AssemblyInfo.cs文件中删除了以下行:[assembly:AssemblyKeyFile(“ yourkeyfilename.snk”)]。然后,此后就没有构建投诉。


谢谢!由于您的回答,我重新检查了我的问题(ClosedXML),并找到了ClosedXML.Signed nuget包。
基里尔

6

我是用nuget安装的ServiceStack dll遇到此问题的。原来,还有另一组标记为已签名的dll可用。并不是每个人都能找到答案,但是您可能只需要检查程序集的现有签名版本即可。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
这是另一种签名。OP要求的是如何使用一个强名称对.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

1
我遇到了WireMock.Net的问题,终于使它工作了,但是花了我一些时间弄清楚PowerShell命令。特别是整个/ lib参数,最终使ILMerge对程序集进行签名。
弗朗索瓦(François)'18年

1> Register-PackageSource -ProviderName NuGet -Name NuGet -Location http://www.nuget.org/api/v2
弗朗索瓦(François)'18年

2> Install-Package -Name ILMerge
弗朗索瓦(François)

3> $env:path += ';C:\Program Files\PackageManagement\NuGet\Packages\ilmerge.2.14.1208\tools'
弗朗索瓦(François)'18年

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)'18年

1

情况:您在解决方案X,Y中有项目A,B,C,D

X中的A,B,C项目Y中的A,C,D项目

我需要在项目A中使用项目C,但是以后我不使用。在bin调试项目A中有C.dll。

如果我编译解决方案X,一切都很好(在此解决方案中,我删除引用A->C。),但是在解决方案YI中,出现此问题。

解决方案是删除项目A bin调试中的C.dll


0

首先,确保解决方案中所有项目的所有nuget软件包都具有相同的版本。例如,您不希望一个项目引用NLog 4.0.0.0,而另一个项目引用NLog 4.1.0.0。然后尝试使用重新安装nuget软件包

更新包-重新安装

我的程序集A引用了3个第三方程序集,而我的程序集B也引用了2个第三方程序集。

通过update package命令添加了对第3方程序集的缺失引用,该错误消失了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.