欢迎光临
我们一直在努力

Assembly学习心得(2)-.NET教程,评论及其它

建站超值云服务器,限时71元/月

第二部分(例子)
  
   下面是一个完整的例子来逐一说明上面所提到的概念,以加深理解。
   整个例子包含7个文件(在主目录下):
   主目录为 …/assembly —-源程序目录
   …/assembly/bin —- 编译结果输出的目录,也就是应用程序主目
  
   录。
  
  
  
   文件名
   类型
   说明
  
   app.cs
   code源文件
   主程序,包含程序入口,
   属于namespace1
  
   classa.cs
   code源文件
   类型a,包含一个静态方法,
   属于namespace1
  
   classb.cs
   code源文件
   类型b,包含一个静态方法,
   属于namespace2
  
   assemblyinfo.cs
   code源文件
   包含程序集签名信息,
   版本信息等
  
   app.key
   公钥/私钥对文件
   用来给程序集签名,
   生成强命名程序集
  
   app.publickey
   只包含共有密钥
   只储存共有密钥,
   用sn.exe来查看
  
   app.exe.config
   xml格式配置文件
   app.exe的应用程序配置文件
  
   源代码
   app.cs
   namespace namespacea {
   public class app {
   static void main (string[] args) {
   system.console.writeline(classa.showme());
   system.console.writeline(namespaceb.classb.showme());
   }
   }
   }
   classa.cs
   namespace namespacea {
   public class classa {
   public static string showme()
   {
   return “this is classa”;
   }
   }
   }
  
   classb.cs
   namespace namespaceb {
   public class classb {
   public static string showme() {
   return “this is classb”;
   }
   }
   }
   assemblyinfo.cs
   ////////////////////////////////////////////////////////////////////////////////
   // module: assemblyinfo.cs
   ////////////////////////////////////////////////////////////////////////////////
   using system.reflection;
   ////////////////////////////////////////////////////////////////////////////////
   // set companyname, legalcopyright, and legaltrademarks
   [assembly: assemblycompany(“app company”)]
   [assembly: assemblycopyright(“copyright (c) 2004 @ app company”)]
   [assembly: assemblytrademark(“app is a test only program”)]
   ////////////////////////////////////////////////////////////////////////////////
   // set productname and productversion
   [assembly: assemblyproduct(“app product”)]
   [assembly: assemblyinformationalversion(“1.0.0.0”)]
   ////////////////////////////////////////////////////////////////////////////////
   // set fileversion and assemblyversion
  
   [assembly: assemblyfileversion(“1.0.0.0”)]
   [assembly: assemblyversion(“1.0.0.0”)]
   [assembly: assemblytitle(“app type assembly”)]
   [assembly: assemblydescription(“app aassembly is a test only assembly”)]
  
   ////////////////////////////////////////////////////////////////////////////////
   // set culture
   [assembly: assemblyculture(“”)]
   [assembly: assemblydelaysign(false)]
   [assembly: assemblykeyfile(“app.key”)]
   [assembly: assemblykeyname(“”)]
   app.key和app.publickey是二进制格式存储的,不能直接查看。后面例子中会用到
  
   1. 把源代码编译为托管模块(managed module)
   csc /out:bin/classa.module /t:module classa.cs
   参数:
   /out: 输出路径
   /t: 输出格式。可以有四种,分别是:
   library —- dll程序集
   exe —- 控制台可执行程序(也是程序集的一种)
   winexe —- windows可执行程序(同样也是程序集的一种)
   module —- 托管模块(程序集的一部分)
  
   说明: 托管模块的的扩展名可以是任意的(也可以没有),因为编译的时候都是以元数据的格式读取的。
  
   2. 把源代码编译为程序集(assembly)
   l 把classb编译为一个单文件程序集
   csc /out:bin/classb.dll /t:library classb.cs
   l 把app.cs,classa.module和classb.dll编译为一个多文件程序集
   csc /out:bin/app.exe /t:exe app.cs /addmodule:bin/classa.module /r:bin/classb.dll
   参数:
   /addmodule: 把托管模块添加到程序集中 /r: 添加引用说明: 上面生成的程序集因为没有经过公钥/私有签名,所以生成的是非强命名类型的程序集。 生成的程序集app.exe的清单中只包含对classa.module托管模块的说明,并不 包classa.module的元数据,所以app.exe和classa.moudle必须在同一目录中。app.exe在运行时,如果用到对classa.module中类型的引用,则会去classa.moudel文件进行查找,如果classa.moude文件不存在,则会引发system.io.filenotfoundexception。如果app.exe不会用到class.module中的类型,则classa.module存不存在都不会对app.exe的执行产生任何影响(这就是上面提到的assembly的好处之一,assembly只是一个逻辑上的组合)。
   app.exe还用到了对classb.dll的引用,因为classb.dll不是一个强命名类型,所以它只能进行私有部署,可以和app.exe放在一起,也可以放在主目录下的其他子目录下。(后面通过应用程序更改配置文件,可以重定向指classb.dll的引用)。
  
   3. 更改应用程序配置文件(app.exe.config),重定向对classb.dll的引用。
  
   现在app.exe,classa.moudle和classb.dll都在bin目录下,app.exe在运行时会找到所有它需要的类型,所以运行正常。
  
   如果把在bin目录下新建一个目录,比如sub,并把classb.dll移动到sub目录下,再运行app.exe就会出错。同样会引发system.io.filenotfoundexception错误,因为app.exe运行时需要的classb类型找不到。这时候就需要更改添加(如果没有)或更改应用程序配置文件,应用程序配置文件是一个xml格式的配置文件,和web.config文件的作用差不多,是配置应用程序运行时的行为的。
  
   注意:配置文件的名字必须是应用程序名字再加一个.config,且必须在同一目录下
   详细信息参考: ms-help://ms.msdnqtr.2004apr.1033/cpguide/html/
   cpconnetapplicationconfigurationscenarios.htm
  
   app.exe.config文件的内容:
   <?xmlversion=”1.0″encoding=”utf-8″?>
   <configuration>
   <runtime>
   <assemblybindingxmlns=”urn:schemas-microsoft-com:asm.v1″>
   <probingprivatepath=”sub”/>
   </assemblybinding>
   </runtime>
   </configuration> 当app.exe运行时,它就会在主目录下的sub目录中找到classb.dll,然后继续行。
   说明:
   当clr需要定位一个程序集时,它将扫描应用程序的几个子目录,下面是才clr扫描一个程序集时的顺序:
   …/assembly/bin/classb.dll.
   …/assembly/bin/classb/classb.dll.
   …/assembly/bin/sub/classb.dll.
   …/assembly/bin/sub/classb/classb.dll.
   …/assembly/bin/classb.exe.
   …/assembly/bin/classb/classb.exe.
   …/assembly/bin/sub/classb.exe.
   …/assembly/bin/sub/classb/classb.exe.
  
   注意: 如果app.exe引用的是强命名程序集,clr会首先在gac中查找,然后才按照上面的顺序查找。
  
   4. 创建和查看公钥/私钥对文件
   创建公钥/私钥对文件可以用.net sdk自带的工具(sn.exe)来创建。 首先,创建一个公钥/私钥对文件
   sn -k app.key
   然后,用这个文件创建只包含共有密钥的文件:
   sn -p app.key app.publickey
   然后用-tp参数查看
   sn –tp app.publickey
   Assembly学习心得(2)-.NET教程,评论及其它
   5. 创建强命名程序集
   有了公钥/私钥对,创建强命名程序集就很容易了。只需要把
   system.reflection.assemblykeyfileattribute特性加到源代码中就可以了。
   [assembly: assemblykeyfile(“app.key”)]
   一般都加到assemblyinfo.cs文件中。
   现在重新build classb.cs,得到的将是一个强命名的程序集:
   csc /out:bin/classb.dll /t:library classb.cs assemblyinfo.cs
  
   用ildasm.exe查看,你会发现,在assembly中的public key会有一大串值,这个就是程序集的公有密钥,它保证了整序集的唯一性。
   [img][/img]
   6. 把强命名的程序集classb.dll加入到gac中。
   使用工具gacutil.exe
   把classb.dll加入到gac中:
   gacutil /i classb.dll
   删除掉classb.dll,然后重新build app.exe:
   csc /out:bin/app.exe /t:exe app.cs /addmodule:bin/classa.module /r:classb.dll
   app.exe运行正确,表明classb.dll已经成功加入到gac中,成为一个共享程序集了。 程序集相互引用的规则:
  
   程序集种类
   是否可以引用弱命名程序集
   是否可以引用强命名程序集
  
   普通程序集
   是
   是
  
   强命名程序集
   否
   是
  
  
   把classb.dll移出gac: gacutil /u classb
   注意:
   移出的时候不能指定扩展名(因为在gac中每一程序集对于对应的都是一个目录,而不是实际的程序集)。
  
   如果classb.dll不是一个强命名的程序集,而你想把app.exe build为一个强命名的,就会出错:
   error cs1577: assembly generation failed — referenced assembly classb does not have a strong name
   你可以试一试。j
  
   7. 并行执行(side-by-side)的例子
   http://www.microsoft.com/china/msdn/archives/library/
   dnnetdep/html/sidexsidenet.asp
  
   参考资料:
   l applied microsoft .net framework programming —- jeffrey richter
   l msnd library
   l 感谢刘琳的大力帮助。
  
   <end>

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » Assembly学习心得(2)-.NET教程,评论及其它
分享到: 更多 (0)