如何修复“引用的程序集没有强名称”错误

Posted

技术标签:

【中文标题】如何修复“引用的程序集没有强名称”错误【英文标题】:How to fix "Referenced assembly does not have a strong name" error 【发布时间】:2010-09-24 19:06:00 【问题描述】:

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

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

我需要签署这个第三方程序集吗?

【问题讨论】:

***.com/questions/1220519 这听起来像是一个愚蠢的提示,但是如果您发现无论您做什么,您的程序集都没有得到签名,请检查您的构建设置;请记住,当您重建/清理时,VS 不会清除其他架构(任何 CPU、x64 等),因此您可能正在查看来自其他架构的过时 dll。 @jrh 我的构建一直告诉我我的项目没有强命名,但我已经签名了!我什至安装了 StrongNamer nuget 包,但它仍然抱怨程序集未签名。这种故障排除是最令人不快的事情之一。 【参考方案1】:

签署第三方程序集对我有用:

Referenced assembly does not have a strong name

我了解到,如果链接的文章不再有效,发布步骤会很有帮助。所有功劳归Hiren Khirsaria:

    运行 Visual Studio 命令提示符并转到 DLL 所在的目录。

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

    现在使用以下命令创建CIL 文件。

    D:/hiren> ildasm /all /out=Test.il Test.dll(此命令生成代码库)

    生成一个新密钥来签署您的项目。

    D:/hiren> sn -k mykey.snk

    现在使用ilasm 命令为您的库签名。

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

【讨论】:

你的链接成功了!谢谢!它解释了如何创建 mykey.snk (他们的其他答案没有说明如何)【参考方案2】:

我添加了 NuGet 包“StrongNamer”,我的问题解决了。

【讨论】:

【参考方案3】:

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

重新安装 NuGet 包
Update-Package -reinstall

我的程序集 A 引用了三个第三方程序集,而我的程序集 B 也引用了 A 的引用中只包含了两个。

更新包命令添加了对第三方程序集的缺失引用,错误消失了。

【讨论】:

【参考方案4】:

使用 ilmerge。 ilmerge 来自 Microsoft,但它并未随 Visual Studio 或 SDK 一起提供。您可以从here 下载它。还有一个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(来自 Visual Studio)生成自己的密钥文件:

sn -k key.snk

【讨论】:

我遇到了 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【参考方案5】:

我在使用 NuGet 安装的 ServiceStack DLL 文件时遇到了这个问题。原来还有另一组标记为已签名的 DLL 文件可用。不会是每个人的答案,但您可能只需要检查您的程序集的现有签名版本。

【讨论】:

【参考方案6】:

对我来说,我的问题是我安装了两个相同的 NuGet 包,但版本不同。

【讨论】:

【参考方案7】:

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

(您可能会注意到,屏幕截图来自 Visual Studio 2010,但希望它对某人有所帮助。)

【讨论】:

我没有在我的 MVC 项目中检查这个设置。但它仍然在抱怨其中一个依赖项。 MVC 还有其他设置吗?【参考方案8】:

我编写了一个工具来自动对程序集进行强名称签名,包括您没有源代码的程序集或已放弃的项目。它以简单的方式使用了答案中描述的许多技术,没有现有工具或过时说明的任何缺陷或缺点。

.NET Assembly Strong-Name Signer

我希望这可以帮助任何需要签署第三方程序集的人,而不必费劲儿就可以到达那里。

【讨论】:

【参考方案9】:

对我来说,问题在于没有强名称的 NuGet 包。解决方案是从 NuGet 安装 StrongNamer,它会自动为所有引用的程序集添加一个强名称。只需在项目中引用它即可解决我的问题。

【讨论】:

我发现 StrongNamer 的一个问题是重新签名解决方案似乎没有受到影响:调试器中的数据提示在使用该库的任何方法中都不起作用。或者至少他们没有在我使用过的一个项目中。我回去做了完整的重新签名(这是 PITA,因为它是一个可能会在某个时候更新的 NuGet 项目),并调试现在可以正常工作了。 @RobinHood70 我没遇到过这个问题,但是我用的是JetBrains Rider【参考方案10】:

展开正在使用不“具有强名称密钥”的项目的项目文件并查找.snk 文件 (.StrongNameKey)。

浏览到Windows Explorer 中的这个文件(只是为了让您知道它在哪里)。

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

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

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

希望对你有帮助。

【讨论】:

如果我不想签署我的程序集,我就不会从一开始就签署它! 如果您没有找到 .snk 文件:打开项目属性(使用带有“强名称”错误的项目的项目),选项卡签名。在那里,您将看到用于签署项目的文件(并不总是带有 .snk 扩展名的文件)。只需将此设置复制到其他项目即可。 正如 MrOli3000 指出的那样,它仅适用于缺少强名称密钥文件的一种解决方案。如果有多个项目会引用未签名的项目,您最好创建一个新的强名称密钥文件以避免任何冲突。在我的情况下,解决方案没有建立,我正在兜圈子试图修复。从 VS2017 开始,格式为 .pfx 而不是 .snk,但步骤相同 - 右键单击​​解决方案并选择属性。从左侧列出的选项卡中,选择“签名”。单击复选框并选择新... 提供名称!瞧!完成了!)【参考方案11】:

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

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

我需要在项目 A 中使用项目 C,但后来我不使用了。在 bin Debug 项目 A 中有 C.dll。

如果我编译解决方案 X,一切都很好(在这个解决方案中,我删除了参考 A -> C.),但是在解决方案 Y 中我遇到了这个问题。

解决办法是删除项目A bin Debug中的C.dll

【讨论】:

【参考方案12】:

为避免此错误,您可以:

动态加载程序集,或 签署第三方程序集。

您将在 .NET-fu: Signing an Unsigned Assembly (Without Delay Signing) 中找到有关签署第三方程序集的说明。

签署第三方程序集

签署第三方的基本原则是

    使用ildasm.exe反汇编程序集并保存中间语言(IL):

    ildasm /all /out=thirdPartyLib.il thirdPartyLib.dll 
    

    重建并签署程序集:

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

修复附加引用

上述步骤工作正常,除非您的第三方程序集 (A.dll) 引用另一个也必须签名的库 (B.dll)。您可以使用上述命令对 A.dllB.dll 进行反汇编、重建和签名,但在运行时加载 B.dll将失败,因为 A.dll 最初是使用对 B.dllunsigned 版本的引用构建的。

解决此问题的方法是修补上述步骤 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

【讨论】:

因此对程序集进行签名是一个选项,我既不想动态加载程序集也不想对其进行签名。我知道强命名与全局程序集缓存(GAC)有关。尽管如此,我不想让我的程序集成为 GAC 的一部分,它们也不是 COM 可见的。我记得部分记得我们可能会做的一些事情,这将允许在不签署它的情况下使用这个程序集。它位于选项属性中的某个位置左右。我想走那条路吗? 如果您的程序集也未签名,您可以使用未签名的程序集。 .NET-fu 的链接是一个很棒的资源 虽然上述步骤在“大多数”情况下都可以工作,但它非常耗时且容易出错,并且会因朋友程序集引用而失败。只需使用此实用程序自动完成所有操作(无耻插件):***.com/a/19459609/564726 @Roel 我已经详细说明了这里的过程delabs.io/the-12th-labor-of-a-net-developer-part-4【参考方案13】:

删除 “签名”选项卡下的 “签署程序集” 复选标记,正如@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)"

您可以签署其他人的文件或自己的​​文件,数量不限。

【讨论】:

这是一种不同的签名方式。 OP 要求的是如何使用强名称签署 .NET 程序集。您将展示如何使用代码签名证书对可执行文件进行签名。不同的东西。【参考方案14】:

如果您的程序集也未签名,您可以使用未签名的程序集。

【讨论】:

【参考方案15】:

How to sign an unsigned third-party assembly

    打开 Visual Studio 的开发人员命令提示符。此工具可在您的 Window 程序中使用,并且可以使用默认的 Windows 搜索找到。 通过执行一次确保您的提示可以访问以下工具:sn ildasmilasm 导航到 Cool.Library.dll 所在的文件夹 sn –k Cool.Library.snk 创建新的密钥对 ildasm Cool.Library.dll /out:Cool.Library.il拆库 move Cool.Library.dll Cool.Library.unsigned.dll 保留原始库作为备份 ilasm Cool.Library.il /dll /resource=Cool.Library.res /key=Cool.Library.snk 用强名称重新组装库 powershell -command "& [System.Reflection.AssemblyName]::GetAssemblyName($args).FullName Cool.Library.dll" 获取程序集完全限定名称。如果您必须在 web.config 或 app.config 等外部配置文件中引用 DLL,您将需要此位。

【讨论】:

【参考方案16】:

对于一个强命名的应用程序,我遇到了这个问题,然后必须更改它才能引用非强命名程序集,所以我在项目属性签名部分取消选中“签署程序集”,但它仍然 抱怨。我认为它必须是导致问题的某个地方的人工制品,因为我正确地完成了其他所有操作,仅此而已。我从它的 assemblyInfo.cs 文件中找到并删除了这一行: [assembly: AssemblyKeyFile("yourkeyfilename.snk")] 。 之后就没有构建投诉了。

【讨论】:

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

以上是关于如何修复“引用的程序集没有强名称”错误的主要内容,如果未能解决你的问题,请参考以下文章

错误修复程序和测试集如何不兼容?

安装了精简版的windows 的电脑如何修复?参照的程序集没有安装在系统上

在 Keras 中加载数据集时如何修复错误?

程序集致命错误 LNK1190:找到无效修复,类型 0x0001

如何修复 FxCop 错误代码 512?

如何修复('throw er; //未处理'错误'事件')代码生命周期?