私有部署:何谓私有部署这是相对公有部署而言的,我们知道在安装了dotNetFramework的机器上%SystemRoot%/assembly(%SystemRoot%一般指系统Windows目录)目录中的文件是.net运行必需的组件,然而在我们自己的可执行程序中需要的组件,存放在程序的根目录下的dll组件(也称作程序集文件)。对这些文件的部署就称为私有部署。当然也可以部署到公用程序集缓存中(也称作GAC,若要部署GAC不能单纯的把dll复制到assembly目录,这里需要一个部署工具GACUtil.exe,关于这个工具的使用请查看MSDN,这里不在详细阐述)程序运行需要调用的组件 部署在程序根目录下。后面我会讲到如何组织dll组件。
开始我们的正式行程:
以下内容提到的程序集文件,dll,组件意义相同。
这里我们首先编译一个dll组件(这里的代码无任何实用功能,仅作演示)
命令行执行csc.exe /out:Utildata.dll /t:library /r:Dataprovider.cs
得到UtilData.dll文件
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
UtilData
...
{
public class DataProvider
...{
public DataProvider() ...{ }
public DataProvider(Int32 _id, String _name, String _sex)
...{
id = _id;
name = _name;
sex = _sex;
}
private Int32 id;
private String name;
private String sex;
public Int32 ID
...{
get ...{ return this.id; }
set ...{ if (value >= 0) ...{ this.id = value; } }
}
public String Name
...{
get ...{ return this.name; }
set ...{ if (value != null) ...{ this.name = value; } }
}
public String Sex
...{
get ...{ return this.sex; }
set ...{ if (value != null) ...{ this.sex = value; } }
}
public String GetDataProvider(Int32 id)
...{
return "You id is:" + id.ToString();
}
public override string ToString()
...{
//return base.ToString();
StringBuilder sb = new StringBuilder();
sb.Append("My id:" + this.id);
sb.Append("My name:" + this.name);
sb.Append("My sex:" + this.sex);
return sb.ToString();
}
}
}
创建winapplication窗体程序界面如下,添加引用,找到刚才生成的dll组件

Test按钮后台代码:
//
my code
UtilData.DataProvider dp
=
null
;
private
void
btnCall_Click(
object
sender, EventArgs e)
...
{
dp = new UtilData.DataProvider(001, "fang", "man");
MessageBox.Show(dp.ToString());
}
生成项目,我们可以发现在项目debug目录结构如下:

Ⅲ:你可以发现我的!~!(dll私有部署到根目录下的任意文件夹下)
在实际应用中我们往往会吧dll组件分布在应用程序根目录下的不同文件夹下,我们应该如何做呢?
clr会找到运行时需要的组件吗?这就需要.config文件的支持了,在根目录新建一个和可执行程序同名的config文件,比如privatePublish.exe 的config文件文件名称为privatePublish.exe.config,clr在加载privatePublish.exe是会按照.config配置的信息运行程序。
privatePublish.exe.config文件,这里列的条目比较简单,详见MSDN,Lib就是存放dll组件的目录
如果有多个目录用分号分开(比如dll组件目录需要两个文件夹则privatePath="Lib;SupDll")clr会自动在寻找所需的程序集文件。
<
configuration
>
<
runtime
>
<
assemblyBinding
xmlns
="urn:schemas-microsoft-com:asm.v1"
>
<
probing
privatePath
="Lib"
/>
</
assemblyBinding
>
</
runtime
>
</
configuration
>
目录结构

Ⅳ:没人可以替换我!(dll/exe强命名,使用公钥/私钥给程序集签名,防篡改)
何谓强命名,一个强命名组件包含4个特性:组件名称,语言特性,版本,公钥标记,这4个特性可以唯一的确定程序集。
这里需要介绍个Sn.exe实用工具,它位于.net安装目录。(具体使用方法见MSDN)
我们的目的是要得到公钥标记,所以命令行执行
SN.exe -k myKey.keys 创建公钥/私钥对文件,程序集需要的就是它。
SN.exe -p mykey.keys mykey.publickey 依据公钥/私钥文件,创建公钥文件,为了下一步查看公钥 和公钥标记
SN.exe -tp mykey.pubilckey 控制台显示公钥和公钥标记 我的机器上运行此步骤截屏

要生产强命名的UtilData.dll文件执行如下命令行
csc.exe /out:Utildata.dll /t:library /keyfile:my.keys /r:Dataprovider.cs
这与之前生成的UtilData.dll唯一不同就是指定了keyfile:my.keys 开关。当然亦可以对exe文件添加添加同样的开关对exe也执行强命名
可以在项目属性属性—签名标签中指定keys文件对winexe文件签名

至此就完成了对程序集的私有部署+强命名
做个小试验验证下对强命名程序集的篡改会导致什么后果
Restorator 打开UtilData.dll,

点击保存~!我们对UtilData.dll进行了篡改。
我们运行PrivatePublish.exe 咯问题来了

为什么会这样呢,因为对程序集进行篡改了,修改的UtilData.dll的数据已经不能被调用它的程序集识别了,所以加载程序集出现了错误~!
本文介绍了.NET程序中私有部署的概念及实现方法,并详细解释了如何通过配置.config文件将DLL组件部署到应用程序根目录下的任意文件夹。此外,还探讨了如何利用公钥和私钥对DLL和EXE文件进行强命名,以防止程序集被篡改。
268

被折叠的 条评论
为什么被折叠?



