生成、打包、部署程序集
通过命令将编写的源代码文件编译成程序集有多种方式。可以采用各语言专有的编译器,也可以采用程序集连接器AL。
C#编译器工具CSC
CSC.exe是.net用来编译.cs文件的命令工具。它可以用来生成PE(Portable Executable)文件。PE文件同时也是一个程序集。
CSC的路径默认在framework安装路径下。如:C:\WINDOWS\Microsoft.NET\Framework\版本\csc.exe
如:
csc /out 1.dll /target:library 1.cs /r System.Data.dll;System.dll
说明:/r(refrence):引用部分
/t:(target):生成目标类型
/out:生成文件
例如:在ADOEF工具生成的CS文件中,因为用了global::命名空间标识符,就没有显示dll的引用。这样如果要生成dll就需要通过/refrence开关。
msdn: http://msdn.microsoft.com/zh-cn/library/78f4aasd.aspx
程序调用CSC
在程序中调用外部运行程序,需要使用 System.Diagnostics.Process和 System.Diagnostics.ProcessStartInfo两个类。
如:string strCmd = "/t:library /out:" + 输出路径+ " " +输入路径;
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(@"c:\windows\microsoft.net\framework\v3.5\csc.exe",strCmd);
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
System.Diagnostics.Process.Start(startInfo);
如果需要详细一点的信息。则可以建立一个Process对象,而不是使用静态函数。
如:
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.CreateNoWindow = true;
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = startInfo;
p.Start();
p.StandardInput.WriteLine(strCmd);
p.StandardInput.WriteLine("exit");
string str = p.StandardOutput.ReadToEnd();
应答文件
除了在命令中使用编译器开关,我们也可以通过应答文件(*.rsp)来实现。应答文件是一个文本文件,其中包含了一系列编译器命名开关。使用时可以在应答文件的名称前面加一个@符号:
如:csc.exe @myproject.rsp file1.cs file2.cs
程序集连接器
AL.exe也可以用来创建程序集。该实用程序可以用来创建一个EXE文件或者DLL PE文件。如:
csc /t:module mod1.cs
csc /t:module mod2.cs
al /out:myproject.dll /t:library mod1.netmodule mod2.netmodule
前两条命令生成两个模块:mod1.netmodule,mod2.netmodule
后一条命令通过AL生成一个myproject.dll。
管理控制文件
如果需要在应用程序执行时,进行一些方面的控制,则需要在该应用程序的根目录部署一个xml格式的配置文件。该文件名称必须是应用程序的主程须文件的名称,并附加一个.config扩展名。如:
应用程序:app.exe
配置文件:app.exe.config
强命名程序集
强命名程序集使用发布者的公钥/私钥对进行签名,它唯一性地标识了程序集的发布者。这一对公钥/私钥允许对程序集进行唯一性的标识、保护和版本控制,并允许程序集部署到用户硬盘上的任何地方,甚至部署到Internet上。建议对自己所有的程序集都使用强命名。
一个程序集可以采用私有部署或全局部署。私有部署是指部署到应用程序级目录或者它的某个子目录中的一个程序集。全局部署是指部署到一些已知位置的程序集,CLR在查找程序集时,会检查这些位置。强命名程序集可以进行私有或全局部署。
当两个公司的文件名相同时,如果复制到同一个目录,则最后一个安装的会胜出,这就是DLL hell的根源。因此仅仅通过文件名来区分程序集是不够的。而CLR提供的强命名来对程序集进行唯一标识。它包括4个属性:一个文件名(无扩展名)、一个版本号、一个语言文化(cultrue)标识、一个公钥。公钥非常大,所以我们一般使用公钥标记(64位的哈希值)。
在开发中,如果一个对一个程序集进行强命名,则他引用的所有程序集都必须已经进行了强命名。否则会报错。
强命名程序集主要有以下方式:
命令方式:
1、sn.exe生成一个密钥。如:sn -k myproject.snk
2、csc.exe创建强命名程序集。如:csc /keyfile:myproject.snk myproject.cs
注意:myproject.cs是应用程序中包含清单的程序集文件。
VS方式:
通过属性->签名。勾选“为程序签名”复选框。在下面通过新建方式生成密钥并签名。也可以导入生成的已有密钥。
全局程序缓存(GAC)
如果一个程序集要由多个应用程序访问,就必须把它放到一个已知的目录中,而且CLR在检测到对程序集的一个引用时,必须直到自动检查该目录。这个已知位置为GAC(global assembly cache),它一般在c:\indows\assembly下。
GAC目录是结构化的,并用一个算法来生成这些子目录的名称。GAC的作用是保持强命名程序集与一个子目录的联系。
可以使用工具GACUtil.exe将强命名程序集安装到GAC中。
如:安装 gacutil /i /r myproject.dll
卸载 gacutil /u/r myproject.dll
如果我们发布的应用程序有需要部署到GAC中的程序集,则需要使用windows installer(MSI),MSI是唯一肯定在最终用户机器上,而且能将程序集安装到GAC中的工具。(可以运行MSIExec.exe,查看MSI的版本)。