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编译配置文件,为了加快编译速度,注释了下面的内容:

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

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

2.3. 运行msbuild命令:

  1. msbuild tools/drop.proj

2.4. 编译成功

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

3. 测试已编译的DotNetOpenAuth

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

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

  1. 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文件中

  1. sn -k mykeyfile.pfx

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

  1. sn -i mykeyfile.pfx mykeycontainer

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

  1. sn -p mykeyfile.pfx mykeyfile.pub

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

  1. sn -q -t mykeyfile.pub

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

  1. 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命令:

  1. gacutil /i DotNetOpenAuth.dll

6.3. 却出现错误提示:

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

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

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

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

  1. 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. C#实现的协同过滤算法

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace SlopeOn ...

  2. <数据结构与算法分析>读书笔记--利用Java5泛型实现泛型构件

    一.简单的泛型类和接口 当指定一个泛型类时,类的声明则包括一个或多个类型参数,这些参数被放入在类名后面的一对尖括号内. 示例一: package cn.generic.example; public ...

  3. Python - for 循环

    Python 3  - for 循环 这次将为大家介绍 Python 3 中的 for 循环语句的使用 for 循环的一般格式如下: for <variable> in <seque ...

  4. js基础知识入门总结

    1.第一个js程序 一个项目包括三部分:前端(html.css.js).数据库.后端技术 引入方式:页面中直接写,script标签引入 js事件绑定: <input type="but ...

  5. CentOS7 为firewalld添加开放端口

    1.运行.停止.禁用firewalld 启动:# systemctl start  firewalld 查看状态:# systemctl status firewalld 或者 firewall-cm ...

  6. win10触摸板手势

    尴尬的发现,今天才开始使用win10的手势,之前都是单指操作/笑哭 参考:http://www.sohu.com/a/63678223_230077 https://support.microsoft ...

  7. Android应用安全之脆弱的加密

    程序员希望通过加密来提升程序的安全性性,但却缺乏专业的密码学背景知识,使得应用对数据的保护非常薄弱.本文将介绍可能出现在Android应用中的一些脆弱的加密方式,以及对应的攻击方法. 造成脆弱加密的主 ...

  8. 20155331《网络对抗技术》Exp4:恶意代码分析

    20155331<网络对抗技术>Exp4:恶意代码分析 实验过程 计划任务监控 在C盘根目录下建立一个netstatlog.bat文件(先把后缀设为txt,保存好内容后记得把后缀改为bat ...

  9. Redis学习之路(三)之Redis主从和哨兵模式

    目录 一.Redis主从配置 1.环境说明 2.修改主从的redis配置文件 3.启动主从redis 3.数据同步验证 二.Redis哨兵模式 1.Redis sentinel介绍 2.Redis S ...

  10. winform和wpf如何实现鼠标穿透的效果

    先看一下鼠标穿透的效果: 可以看到Form1这个程序虽然遮在了桌面的上面,但是我们还可以在窗体上点击桌面上的必应词典和网易邮箱大师,好像这个叫“Form1”的窗口被“穿透”一样. winform版本: ...