您的位置:首页 > 编程语言 > C#

c#使用类库编写word插件注意事项

2016-03-04 10:07 435 查看
生成的DLL要使用RegAsm.exe和gacutil.exe这两个工具注册后,再添加注册表项,才能够成功加载插件。

gacutil.exe的位置 win7 net4.5 C:\Program
Files (x86)\Microsoft SDKs\Windows\v8.1A

如果一个程序集要由多个应用程序访问,必须把它放到一个已知的目录中,而且CLR在检测到对该程序集的一个引用时,必须知道自动检查该目录。这个已知的位置称为全局程序集缓存(Global
Assembly Cache,GAC)
。对于.NET3.5和以前的版本,GAC通常位于以下目录(假定Windows安装到C:\Windows目录):

C:\Windows\Assembly

对于.NET4.0,GAC位于以下目录:

C:\Windows\Microsoft.NET\Assembly

  GAC目录是结构化的:其中包含许多子目录,并用一个算法来生成这些子目录的名称。永远不要将程序集文件手动复制到GAC目录;相反,应该使用工具来完成这项任务。这些工具知道GAC的内部结构,并指导如何生成正确的子目录名。

开发和测试期间,为了在GAC中安装一个强命名程序集,最常用的工具是GACUtil.exe。直接运行这个工具,不添加任何命名行参数,会自动显示它的用法:

Microsoft®.NET Global Assembly Cache Utility. Version 4.0.30319.1

Copyright© Microsoft Corporation. All rights reserved.

用法:Gacutil <命令> [<选项>]

命令:

/i <assembly_path> [/r<…>] [/f]

将某个程序集安装到全局程序集缓存中

/il <assembly_path_list_file> [/r<…>][/f]

将一个或多个程序集安装到全局程序集缓存中

/u <assembly_display_name> [/r<…>]

将某个程序集从全局程序集缓存卸载

/ul <assembly_display_name_list> [/r<…>]

将一个或多个程序集从全局程序集缓存卸载

/l [<assembly_name>]

列出通过<assembly_name>筛选出的全局程序集缓存

/lr [<assembly_name>]

列出全局程序集缓存以及所有跟踪引用

/cdl

删除下载缓存的内容

/ldl

列出下载缓存的内容

/?

显示详细帮助屏幕

选项:

/r <reference_scheme><reference_id><description>

指定要安装(/i,/il)或卸载(/u,/ul)的跟踪引用

/f

强制重新安装程序集

/nologo

取消显示徽标版权标志

/silent

取消显示所有输出

  可以看出,可以使用GACUtil.exe的/i开关将一个程序集安装到GAC中,使用/u开关则可从GAC中卸载一个程序集。注意,不能将一个弱命名的程序集放到GAC中。如果将一个弱命名的程序集的文件名传给GACUtil.exe,它会显示错误消息:“将程序集添加到缓存失败:试图安装没有强名称的程序集”。

在GAC中“注册”程序集的目的是什么呢?假定两家公司分别生成了一个名为OurLibrary的程序集,两个程序集都有一个OurLibrary.dll文件构成。显然,这两个文件不能存储到同一个目录中,否则最后一个安装的会覆盖第一个安装的,肯定会破坏一个应用程序。相反,将程序集安装到GAC中,就会在C:\Windows\Assembly目录下创建专门的子目录,程序集文件会复制到其中一个子目录中。

  通常,没人会去检查GAC的子目录,所以GAC的结构对你来说并不重要。只要你使用的工具和CLR知道这个结构,一切都会正常进行。

但是,注意:不能将一个弱命名程序集安装到GAC中。在进行上述2-3种方法安装过程之前,我们必须保证此项目具有强名称才可以。

给项目添加强名称需要以下三步:

1. 在项目调试完成后,使用sn.exe工具生成一个密钥。sn -k "生成的密钥的全路径"。

如在命令行输入: sn -k D:/myKey.snk

2. 将密钥与项目的程序集进行关联: 项目属性-->签名-->为程序集签名-->选择强名称密钥文件。

此外, 还有另外一种方法,就是在项目的AssemblyInfo.cs文件中,修改"AssemblyKeyFile"的属性。

如: [assembly:AssemblyKeyFile("D://myKey.snk")]

3. 重新生成项目集。

RegAsm.exe的位置 win7 net4.0 C:\Windows\Microsoft.NET\Framework\v4.0.30319

使用方法:regasm /codebase "Test.dll"

regasm
不是内部或外部命令解决方法

1.转到需要注册的dll路径

如:C:/GZ/BHOHelloWord/BHOHelloWord/bin/Debug/BHOcc.dll

则在DOS下输入:cd C:/GZ/BHOHelloWord/BHOHelloWord/bin/Debug

2.在1转到的目录下输入:C:/Windows/Microsoft.NET/Framework/v2.0.50727/ragasm /codebase "BHOcc.dll"

3.问题解决

sn.exe的使用

SN.EXE: C:\Program Files\Microsoft
SDKs\Windows\v6.0A\bin\sn.exe

生成的文件在:C:\Program Files\Microsoft Visual Studio 9.0\VC

接上篇,在上一篇中提到了AssemblyName有一部分是public key token。这里有个public key,实际上public key和private key是成对的。顾名思义,public key就是公钥,private key就是私钥。公钥是公开的,私钥是非公开的,而且密级要很高。

CLR用数字签名的方式防止程序集发布后被篡改,而且还可以唯一的确定发布人。这个签名的方法是使用公钥私钥文件,然后对程序集所有模块取一个哈希生成一个数字签名然后放在程序集的元数据中。

当前CLR版本使用RSA 公钥/私钥和Secure Hash Algorithm(SHA)产生数字签名

在SDK中有一个strong name tool,SN.exe,使用这个工具可以生成公钥私钥对:
sn -k publicprivate.snk


这样publicprivate.snk这个文件里就包含公钥和私钥(私钥436个字节,公钥由128个字节和一个32字节的头部组成)

但是私钥这个东西密级很高(大公司应该制定严密的使用私钥的申请制度),我们编写程序的时候要经常部署测试,总不能每次都申请使用一次私钥签名一次吧。微软也想到了这点,就允许我们光使用公钥签名,公钥是公开的,所以这个不涉及密级的问题。SN.exe可以从公钥私钥文件中取出公钥生成一个新文件:

sn –p publicprivate.snk public.snk

这样public.snk里就只包含公钥了,你可以把这个文件放心的发布给所有的开发人员使用这个来签名,但是千万记住,这个只能在测试的时候使用,发布的时候如果使用这个那什么防篡改啊啥的都没用了。为什么呢?

在我们要使用公钥文件签名的时候我们给程序集使用这样的特性:
using System.Reflection;
[assembly:AssemblyKeyFile("public.snk")]
[assembly:AssemblyDelaySign(false)]


注意这里的AssemblyDelaySign,意思是延迟签名,等到真正发布的时候我们再使用私钥签名。

如果使用这种方式签名啊,生成的程序集签名那个地方就会留空,程序集元数据里只有公钥。

好了,现在程序要发布了,我们是不是把公钥私钥文件拿来,然后用vs把程序再编译一遍呢?当然不是,有的时候程序代码非常大,重新编译一次可不是很容易的。

SN.exe还有一个命令行开关可以给程序集重新签名,就是把刚才那个留空的地方填上真正的签名:

sn –R mylib.dll publicprivate.snk

注意,这里使用的是publicprivate.snk,就是包含私钥的那个文件。

这里说完了,那为啥又要有一个public key token呢?

你想啊,public key有128个字节,那么长,我们使用程序集名引用程序集时难道都把这个带上?而且说过,程序集的元数据里记录了该程序集所引用程序集的所有信息,那要全部记录上该多大啊。如是就搞出个public key token这么个东西,这个东西只有8个字节,SN.exe也有个开关从公钥里生成public key token:

sn –t public.snk

这样我们引用程序集就可以使用这样的字符串了:

System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35

那么这个public key token是怎么得来的呢?算法步骤如下:

1、使用SHA1算法从public key得到它的哈希值

2、取出这个哈希值最后的8个字节

3、然后把这8个字节倒排一下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: