引用程序集没有强名称解决方案

一、什么是强名称

强名称是一个由程序集的标识组成并通过公钥和数字签名(针对该程序集生成)加强的名称,其中的标识包括程序集的简单文本名称、版本号和区域性信息。

由于程序集清单包含构成程序集实现的所有文件的文件散列,因此只对程序集中包含程序集清单的一个文件生成数字签名就足够了。强名称相同的程序集应该是相同的。

1、为什么要使用强名称签名

通过签发具有强名称的程序集,您可以确保名称的全局唯一性。强名称还特别满足以下要求:

  • 强名称依赖于唯一的密钥对来确保名称的唯一性。任何人都不会生成与您生成的相同的程序集名称,因为用一个私钥生成的程序集的名称与用其它私钥生成的程序集的名称不相同。
  • 强名称保护程序集的版本沿袭。强名称可以确保没有人能够生成您的程序集的后续版本。用户可以确信,他们所加载的程序集的版本出自创建该版本的同一个发行者。
  • 强名称提供可靠的完整性检查。通过.NET框架安全检查后,即可确信程序集的内容在生成后未被更改过。但请注意,强名称中或强名称本身并不暗含某一级别的信任,例如由数字签名和支持证书提供的信任。
  • 在引用具有强名称的程序集时,您应该能够从中受益,例如版本控制和命名保护。如果此具有强名称的程序集以后引用了具有简单名称的程序集,则您将失去使用具有强名称的程序集带来的好处,并依旧会产生DLL冲突。因此,具有强名称的程序集只能引用其他具有强名称的程序集。

注意:强名称的应用程序只能引用强名称的dll,不能引用未强名称的dll,但是未强名称的dll可以引用强名称的dll。

二、如何设置强名称

上面我们讲了什么是强签名,以及强签名的好处,下面我们来看看如何给应用程序设置强名称。

1、应用程序有源代码

打开vs tool command,如下图所示:

1、生成公钥

然后进入要设置强名称的dll文件所在的路径,使用下面的命令生成签名公钥:

sn -k StrongName.snk

如下图所示:

2、设置签名公钥

将公钥加入项目中,并设置项目属性,设置签名公钥:

最后重新生成项目即可。

1、应用程序没有源代码

如果项目中引用了其它第三方的dll文件,而且还没有源代码,并且此dll文件是没有强名称的程序集,则在编译时会出现类似“程序集生成失败--引用的程序集XXX没有强名称”。

比如我在程序中使用到了Dapper,而Dapper是没有强名称的,所以生成的时候报错了,如下图所示:

这时我们就需要把Dapper变成有强名称的程序集。

1、打开SDK命令提示窗口

我们这里以VS 2012为例打开SDK命令提示窗口,如下图所示:

然后需要进入Dapper.dll文件所在的目录:

2、创建一个新的随机密钥对

使用下面的命令生成一个随机的密钥对。

sn -k Dapper.snk

如下图所示:

3、反编译目标程序集

使用下面的命令反编译目标程序集,该指令会反汇编该dll并生成Dapper.il,如果该dll含有嵌入的resource,则会有Dapper.res文件产生,并有相应的嵌入资源文件产生。

ildasm Dapper.dll /out=Dapper.il

如下图所示:

4、重新编译,附带强命名参数

使用下面的命令重新编译Dapper.dll,然后会附带强命名参数

ilasm Dapper.il /dll /resource=Dapper.res /key=Dapper.snk /optimize

如下图所示:

这样就表示编译成功了。

5、验证签名信息

编译成功以后,我们使用下面的命令来验证重新编译后的dll文件是否带有强名称

sn -v Dapper.dll 

如下图所示:

这就表示重新编译后的dll文件有了强名称。

6、重新引用

编译成功以后,会在目录下面生成这么几个文件:

可以看到:Dapper.dll这个文件是最新生成的,我们在项目里面重新引用上面新编译的Dapper.dll文件,然后重新编译项目:

可以看到,这时就不会报Dapper.dll没有强名称的错误了。其它没有强名称的dll文件也使用同样的方式进行处理。

猜你喜欢

转载自www.cnblogs.com/dotnet261010/p/12401843.html