.Net中消除Dll中的dependency

简介:
 我们在做.Net Class Library项目时常常会遇到这样的问题,我想生成一个dll供其它程序使用,但在我的项目里,又需要引用一些其它的reference,像ActiveX控件或其它dll,而这些控件或dll又没有strong name,不能写入到GAC(Global Assembly Cache)中,因而,在注册使用你的dll时,就必须带上这些引用的控件或dll,才能完成注册。然而,这并不是我们需要的,我们只想提供一个dll给人家用就行了,为什么还要带上一堆的控件或dll呢?别人也不愿意这样。那么,有什么办法解决这个问题呢?

  正好现在做的这个项目就是这种情况,看了一下网上的资料也不多,于是将自己的解决方法share一下,有什么不好的地方,恳请指正。

  大家都知道,在.Net中,如果你试图将一个dll写入到GAC中,那么除了你的dll项目要使用strong name以外,你的项目中用到的其它的控件或dll都需要有strong name,否则,当你注册你的dll时,会提示缺少dependency。这一点让人很烦,但应该有它的好处,利于版本控制。既然是这样,我们只有将引用到的控件或dll都加上strong name,并写入到GAC中,这样在注册你的dll时,就会到GAC中去找它所用到的控件或dll了。那么,如何做呢?大致分两步:

  1、给需要引用的控件或dll加strong name

  这是必须要做的,否则你无法把他们写到GAC中。.Net的SDK提供一个给程序集生成强名的工具,其实不只是生成,还有管理及签名的验证等,只是根据不同的option来的。详细说明请参考MSDN。下面是通过sn创建一个key pair,存储在keyfile.snk中:

%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\sn  - k keyfile.snk

  这样就生成了一个密钥对。如果你的项目中没有引用其它的不带强名的控件或dll的话,只是想把自己的dll写入GAC,那么在你项目的AssemblyInfo.cs中,把AssemblyKeyFile加上,就是你刚才生成的keyfile.snk文件。

[assembly: AssemblyKeyFile( " ..\\..\\keyfile.snk " )]

  这里的路径是指编译后项目输出的相对路径,所以,如果这里写成这样的话(当然你也可以修改),就应该把刚才生成的keyfile.snk拷贝到项目的跟目录下,以确保在编译的时候能找到snk文件。这样,编译后的dll就可以写到GAC中了:

%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil  - i yourdll.dll

  如果你的项目中引用了其它的不带有强名的控件或dll的话,就需要再做下一步。

  2、给不带有强名的控件或dll加上强名

  这里要用到两个工具,也是.Net自带的,tlbimp和aximp。tlbimp是将COM类型库中的类型定义转换为CLR程序集的等效定义,aximp是将COM类型库中的类型定义转换为windows窗体控件,详细说明请参考MSDN。
  假设你要给tom.dll和MSFlxGrd.ocx加上强名:

tlbimp . / nostrongname_dll / tom.dll  / keyfile:. / snk / tom.dll.snk  / out :. / strongname_dll / Interop_tom.dll

aximp .
/ nostrongname_dll / MSFlxGrd.ocx  / keyfile:. / snk / MSFlxGrd.ocx.snk . / snk / AxMSFlxGrd.ocx.snk

  tlbimp还有很多选项可以用,比如/namespace:Namesapce, /reference:FileName, /publickey:FileName等等,这个可以到.Net Command窗口输入tlbimp回车就可以看到很多帮助。不过我们常用比如/namesapce和/reference。/namesapce可以不加,这时用的是默认的比如上例中的Interop_tom。/reference对我们来说一般比较有用,比如上例中的tom.dll有引用了其它的dll,而我们在给tom.dll加了强名之后又不想把它引用的dll都加进来,这时就要用到/reference选项了。比如tom.dll又引用了tom1.dll和tom2.dll,如果我们不加/reference选项,那么在执行完tlbimp之后,在./strongname_dll目录下除了Interop_tom.dll外,还会将tom1.dll和tom2.dll一起加进来。这样就麻烦了,因为我们在使用Interop_tom.dll的时候还要带着它们,可这不是我们需要的。所以我们可以这样做,假设我们已经将tom1.dll和tom2.dll拷贝到/nostrongname_dll目录下了:

tlbimp . / nostrongname_dll / tom.dll  / keyfile:. / snk / tom.dll.snk  / reference:. / nostrongname_dll / tom1.dll  / reference:. / nostrongname_dll / tom2.dll  / namesapce:tom  / out :. / strongname_dll / Interop_tom.dll

  这样,在./strongname_dll目录下就不会再有tom1.dll和tom2.dll了。不过tom1.dll和tom2.dll也应该是加了强名的才行。

  这里,tom.dll.snk、MSFLlxGrd.ocx.snk和AxMsFlxGrd.ocx.snk是根据第一步产生的,每一个dll都要对应一个snk。tom.dll为转换过的dll的名字,没有什么其它含义。另外需要说明的是MSFlxGrd.ocx会产生两个dll,分别是MSFlexGridLib.dll和AxMSFlexGridLib.dll。个人理解为在窗体初始化时会产生一个AxMSFlexGridLib,不知谁有更好的解释?

  这样就把tom.dll和MSFlxGrd.ocx控件加上了强名称并转换为相应的dll了,再把它们写入到GAC中:

%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil  - i tom.dll
%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil 
- i MSFlexGridLib.dll
%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil 
- i AxMSFlexGridLib.dll

  剩下的工作就是将它们重新引用到你的项目中,重新编译,这样生成的dll在注册时就不需要任何dependency了,因为它们已经在GAC中了,打开c:\winnt\assembly即可看到。

  如果要将它们从GAC中删除,则:

%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil  -u  tom.dll
%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil 
-u  MSFlexGridLib.dll
%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\gacutil 
-u  AxMSFlexGridLib.dll

tom、MSFlexGrid和AxMSFlexGrid为GAC中的名字,这里不需要加任何路径。

   本文转自loose_went博客园博客,原文链接:http://www.cnblogs.com/michaelxu/archive/2007/04/17/717396.html ,如需转载请自行联系原作者


相关文章
|
1月前
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
8 0
|
小程序 C# Windows
|
Windows
一起谈.NET技术,.NET动态调用DLL的方法
  很多软件都是可插拔的,最知名的便是微软的Windows操作系统。你可以在Windows操作系统上安装QQ,也可卸掉QQ,这便是可插拔。这里不谈Windows的实现,因为太过复杂。本文就谈谈管理软件的可插拔的实现。
1438 0
|
Web App开发
一起谈.NET技术,Silverlight动态加载DLL
  问题   今天手头的项目遇到一个问题,为了描述这个问题,我建立了一个简单的项目,结构如下:   问题是这样的:   1,silverlightApplication1中有一个按钮,点击后弹出窗口;silverlightApplication6中只有一个canvas来放置从SilverlightApplication1.dll反射得到的控件。
909 0
|
开发框架 .NET 开发工具
检查.net dll构建的目标平台是any cpu、x86、x64
原文:检查.net dll构建的目标平台是any cpu、x86、x64 有时候,需要检查构建的dll是否针对正确的平台 可以使用CorFlags.exe(它是.NET Framework SDK的一部分)从dll中查找此信息。
1199 0
C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件。
原文:C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件。 当某个程序集文件被载入AppDomain,该文件在AppDomain.Unload之前是不能被替换和删除的。
2296 0