1. 背景

最近在研究DotNetOpenAuth——OAuth的一个.NET开源实现,官方网站:http://dotnetopenauth.net/

GitHub签出DotNetOpenAuth的源代码发现最新版本已到5.1,而NuGet中发布的版本只是4.3。新版中使用到了.NET 4.5的异步特性(async, await),于是决定直接用最新版。

用最新版,就要自己进行编译。用Visual Studio 2012打开解决方案文件进行编译,一次编译成功,但编译出的DotNetOpenAuth相关dll有20个,这么多dll引用起来不方便。发现DotNetOpenAuth提供了msbuild的配置文件,可以在编译时自动将dll文件进行合并(使用了ILMerge)。于是改用msbuild命令进行编译。

2. 用msbuild进行第一次编译

2.1. 使用的是DotNetOpenAuth的tools\drop.proj编译配置文件,为了加快编译速度,注释了下面的内容:

<!--<ItemGroup>
<ProjectsToBuild Include="$(ProjectRoot)samples\samples.proj">
<Properties>TargetFrameworkVersion=v4.5</Properties>
</ProjectsToBuild> --><!-- Sandcastle doesn't seem to be able to handle .NET 4.0 dependencies right now. --><!--
<ProjectsToBuild Include="$(ProjectRoot)doc\doc.proj">
<Properties>TargetFrameworkVersion=v4.5</Properties>
</ProjectsToBuild>
</ItemGroup>-->

2.2. 运行VS2012的命令行:Developer Command Prompt for VS2012

2.3. 运行msbuild命令:

msbuild tools/drop.proj

2.4. 编译成功

2.5. 在drops\v4.5\Debug文件夹中得到合并后的DotNetOpenAuth.dll。

3. 测试已编译的DotNetOpenAuth

3.1. 在另外的项目中引用已编译出的DotNetOpenAuth.dll

3.2. 编译后运行项目,出现错误提示:

Could not load file or assembly 'DotNetOpenAuth' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key. (Exception from HRESULT: 0x80131045)

从这个错误信息中可以解读出:需要对DotNetOpenAuth进行强签名。

4. 使用强签名进行msbuild编译

4.1.  生成公钥

生成公钥需要借助sn.exe(sn是Strong Name的缩写),它是Visual Studio/Windows SDK中自带的一个工具。运行sn.exe命令需要进入Developer Command Prompt for VS2012。

具体操作步骤如下:

4.1.1. 生成密钥对(公钥/私钥)并保存至.pfx文件中

sn -k mykeyfile.pfx

4.1.2. 将密钥对从文件安装至密钥容器中

sn -i mykeyfile.pfx mykeycontainer

4.1.3. 从存放密钥对的.pfx文件中导出公钥至.pub文件

sn -p mykeyfile.pfx mykeyfile.pub

4.1.4. 显示.pub文件中存放的公钥

sn -q -t mykeyfile.pub

4.2. 使用生成的公钥进行msbuild编译

msbuild /p:KeyPairContainer=mykeycontainer,PublicKeyFile="<full path>mykeyfile.pub" tools/drop.proj

4.3. 编译成功

5. 测试已进行强签名编译的DotNetOpenAuth

原以为问题到此就解决了,哪知测试结果出人意料——同样的错误!。。。后来恍然大悟,不放在GAC中,强签名怎么会起作用呢?

6. 将DotNetOpenAuth注册到GAC

6.1. 进入Developer Command Prompt for VS2012命令行

6.2. 运行gacutil命令:

gacutil /i DotNetOpenAuth.dll

6.3. 却出现错误提示:

Failure adding assembly to the cache: Strong name signature could not be verified.  Was the assembly built delay-signed?

6.4. 解决方法——用sn命令忽略对强签名进行验证:

sn -Vr *,<之前创建的公钥>

6.5. 然后再运行gacutil,注册就成功了。

Assembly successfully added to the cache

7. 测试已注册至GAC的DotNetOpenAuth

7.1. 本以为到这里应该大功告成了。。。可是在VS2012中添加引用时,在Assemblies中怎么也找不到DotNetOpenAuth。

DotNetOpenAuth不是已经注册到GAC中了吗?Assemblies不就是GAC中的assemblies吗?

7.2. 搜索网上的资料才了解到Visual Studio添加引用时的Assemblies与GAC一点关系没有,GAC是.NET程序运行时用到的东西,而且这里的assemblies只是VS专用的一个存放程序集的文件夹。可是我以前一直以为它显示的就是GAC中的程序集。是因为我的愚蠢呢,还是因为微软反直觉的设计?即使前者,好的设计应该——别让用户发呆(推荐阅读别让用户发呆——设计中的防呆策略)。

8. 问题解决

按通常的做法,在VS中添加引用时,选择Browse,选择DotNetOpenAuth.dll所存放的文件路径,点击OK。成功引用之后,编译/运行项目,就大功告成了。你会发现,已经在GAC中注册过的程序集,添加引用时,VS将自动将Copy Local属性设置为False;否则为True。这就是程序集在与不在GAC中的一个区别之处。

9. 参考资料

https://github.com/DotNetOpenAuth/DotNetOpenAuth/wiki/ContributorQuickStart

从编译DotNetOpenAuth中学到的程序集强签名知识的更多相关文章

  1. .net程序集强签名

    要想得到强签名的dll有两种情况: 1.给项目添加强命名 在你的项目右键->属性->签名,勾选"为程序集签名",新建 或 浏览已经新建过的.pfx文件,然后重新buil ...

  2. .Net程序集强签名详解

    强签名: 1. 可以将强签名的dll注册到GAC,不同的应用程序可以共享同一dll. 2. 强签名的库,或者应用程序只能引用强签名的dll,不能引用未强签名的dll,但是未强签名的dll可以引用强签名 ...

  3. 程序集生成失败 -- 引用的程序集“ThoughtWorks.QRCode”没有强名称,为没有源码的程序集强签名

    如果你写的程序程序集是带签名的,应用了没有签名的程序集,编译就会报下面的错误 引用的程序集“**”没有强名称 进入sdk提示符界面,依次输入如下指令 sn -k ThoughtWorks.QRCode ...

  4. .NET:强签名程序集的加载问题 之 版本重定向

    背景 多数解决方案会包含多个项目,某些支持插件架构的解决方案中,更是包含多个插件项目,这些项目会使用一些第三方NuGet Packages,如果管理不慎,解决方案中会出现多个版本的引用,这在编译期间不 ...

  5. Python 笔试集(3):编译/解释?动态/静态?强/弱?Python 是一门怎样的语言

    面试题 解释/编译?动态/静态?强/弱?Python 到底是一门怎样的语言? 编译 or 解释? 编译.解释都是指将(与人类亲和的)编程语言翻译成(计算机能够理解的)机器语言(Machine code ...

  6. [.NET] - Enhanced Strong Naming (加强版的强签名程序集) – 如何迁移原有的强命名程序集

    依据文档: https://msdn.microsoft.com/en-us/library/hh415055(v=vs.110).aspx 虽然文档上给出了看似完整的步骤,但是如果按照上面的步骤,结 ...

  7. dll强签名的由来和作用

    C# dll强签名介绍 之前基本没有这个概念,直到有一天我们的dll被反编译了,导致我们的代码基本上被看到了,才想起来要保护dll的安全性,因为C#语言的在编译过程中会产生中间语言导致dll很容易被反 ...

  8. 使用InternalsVisibleToAttribute给assembly添加“友元assembly”特性遭遇"强签名"

    一.如何让Intenal成员暴露给另一个程序集 我们知道Modifier为Internal的类型成员仅限于当前程序集能够访问,但是在某些情况下,我们希望将它们暴露给另一个程序集.比较典型的应用场景包括 ...

  9. VS报:"dll标记为系统必备组件,必须对其进行强签名"错误

    问题: VS生成程序时,报“要将程序集“XX.dll”标记为系统必备组件,必须对其进行强签名.”错误. 解决方法: 1)在报错的解决方案中找到一个可以发布的项目(引用该XX.dll的项目未必可以发布) ...

随机推荐

  1. android 实现mqtt消息推送,以及不停断线重连的问题解决

    前段时间项目用到mqtt的消息推送,整理一下代码,代码的原型是网上找的,具体哪个地址已经忘记了. 代码的实现是新建了一个MyMqttService,全部功能都在里面实现,包括连服务器,断线重连,订阅消 ...

  2. tomcat Win10 配置环境变量详解

    在Win10系统总该如何配偶之tomcat 环境变量?今天win10之家给大家带来了关于win10系统中配置tomcat环境的操作方法.在配置之前我们需要做以下几点: 步骤:安装和配置好了Java 的 ...

  3. Mac svn使用学习-4-客户端cli命令详解

    客户端cli的使用 WC:Working Copy 你的工作区 将文件或目录版本化,这样下一次提交到存储库的时候,他们就都会被提交上去.能实现版本化的命令有: add 1.import 是否访问存储库 ...

  4. Python2.7-zlib

    zlib 模块,提供了压缩和解压缩的函数,都是对字符串进行操作的,可以理解为是各种不同类型的数据经过处理成为字符串或是二进制字符串,再进行压缩解压缩.是和 gzip 相兼容的压缩模块 模块方法: zl ...

  5. Android Bundle传递对象

    首先Android的Bundle是可以传递对象的.我们可以用Bundle b = new Bundle():b.putSerializable("key", 对象引用); 但是这样 ...

  6. 【转】常见的Web实时消息交互方式和SignalR

    https://www.cnblogs.com/Wddpct/p/5650015.html 前言 1. Web消息交互技术1.1 常见技术1.2 WebSocket介绍1.3 WebSocket示例 ...

  7. 20155305《网络对抗》Web安全基础实践

    20155305<网络对抗>Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? 原理:SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL ...

  8. [Python]-pip-ReadTimeoutError: Read timed out 问题

    问题描述 就是在安装Python包的时候,由于时间太长引起的超时问题 问题解决 第一个办法是更改源地址:在 ~/.pip/ 下创建文件 pip.conf(如果还没有的话), 模版如下: [global ...

  9. DynamicDataDisplay 实时曲线图的使用和沿轴移动的效果

    原文:DynamicDataDisplay 实时曲线图的使用和沿轴移动的效果         由于项目需要,最近在找关于绘制实时曲线图的文章,但看了很多自己实现的话太慢,所以使用了第三方控件来实现(由 ...

  10. springboot的热部署和dubug

    采用了项目聚合,产生一些不同,遇到的问题和解决方法分享下. 项目结构: rebuilder2 -htran 主项目 -htran-api 1.htran.pom <parent> < ...