Manifest介绍
本文转自:http://lujf1978.blog.163.com/blog/static/2320126620092454510222/
1 版本问题:DLL Hell
从客户的角度,最常见的版本问题就是我们所说的 DLL Hell 问题。简单地讲, DLL Hell 是指当多个应用程序试图共享一个公用组件(如某个动态连接库(DLL)或某个组件对象模型(COM) 类)时所引发的一系列问题。最典型的情况是,某个应用程序将要安装一个新版本的共享组件,而该组件与机器上的现有版本不向后兼容。虽然刚安装的应用程序运 行正常,但原来依赖前一版本共享组件的应用程序也许已无法再工作。在某些情况下,问题的起因更加难以预料。比如,当用户浏览某些 Web 站点时会同时下载某个 Microsoft ActiveX? 控件。如果下载该控件,它将替换机器上原有的任何版本的控件。如果机器上的某个应用程序恰好使用该控件,则很可能也会停止工作。
在许多情况下,用户需要很长时间才会发现应用程序已停止工作。结果往往很难记起是何时的机器变化影响到了该应用程序。用户可能会回忆起一周前安装了一些东西,但安装与目前看到的状态并没有任何明显的关联。 更糟的是,现在很少有诊断工具帮助用户(或帮助他们的技术支持人员)确定有什么问题。
这些问题的原因是应用程序不同组件的版本信息没有由系统记录或加强。而且,系统为某个应用程序所做的改变会影响机器上的所有应用程序—现在建立完全从变化中隔离出来的应用程序并不容易。
很 难建立一个隔离应用程序的一个原因是当前运行时环境只允许单独版本组件或应用程序的安装。这个限制意味着组件的编写者必须以向后兼容的方式编写他们的代 码,否则当他们安装新组件的时候会有终止已有应用程序的风险。实际上,如果可能的话,编写永远向后兼容的代码是非常难的。在 .NET中,side by side 概念是版本问题的核心。"Side by side" 是在同一台机器上同时运行不同版本的相同组件的能力。使用支持并列的组件,编程人员不必努力维护严格的向后兼容,因为不同的应用程序自由使用某个共享组件的不同版本。
2 Windows中的WinSxS目录
随着系统资源越来越丰富,硬盘不那么紧张,为了解决不同程序的版本问题,微软在XP以后的操作系统中引入了一种“支持COM和共享DLL的隔离 ”机制,使用这种新的机制来管理DLL 。这种机制,不仅仅被.NET平台采用,而且也被Native程序采用。
如此一来,在Windows XP以后的系统中,在“Windows”目录下就多了一个名为“WinSxS”(Windows Side-by-Side)的文件夹。系统使用这个文件夹存储各个版本的Windows XP组件,减少因为动态链接库(Dynamic Link Libraries,DLL)引起的配置问题(DLL hell)。组件的多个版本都存储在这个文件夹中。Windows XP允许Win32 API组件和应用程序使用与这些程序在测试时所使用的版本完全一致的Microsoft 组件版本,并且不受其它程序或者操作系统升级的影响。Windows XP通过XML文件来实现这一功能,这些XML文件保存了有关应用程序配置的元数据,例如COM类、接口和类型库。
3什么是Manifest
“Windows XP通过XML文件来实现这一功能,这些XML文件保存了有关应用程序配置的元数据”,这里所说的XML文件,就是Manifest清单文件。
Manifest事实上就是一个以.manifest为后缀的XML文件,用于组织和描述隔离应用程序及并行组件,其内部的信息如<assemblyIdentity>元素则标识着一个唯一的程序集,和其他信息一起,他们用于COM类、接口及库的绑定和激活,而这些信息,以往都是存储在注册表中的。另外,Manifests也制定了组成程序集的文件及Windows类。
4 Manifest的分类
在Windows XP中,事实上是在.NET中,把Manifests分类为如下几种类型:
l 程序集Manifests(Assembly Manifests):主要用于描述程序集,管理程序集的名字、版本、资源、依赖程序集。其中共享程序集的Manifests存储在Windows的WinSxS目录中。私有的程序集Manifests则存可以作为一个资源存储在DLL中,也可以存储在应用程序目录下。
l 应用程序Manifests(Application Manifests):这类Manifests则用于描述隔离应用程序,它管理着此应用程序在运行时要绑定的共享的并行组件的名字、版本。该Manifests可以作为一个文件(.manifest文件)存储在应用程序相同的目录下,也可以作为一种资源嵌入在可执行文件内部(Embed Manifest)。
l 应用程序配置文件(Application Configuration Files):对于并行组件及隔离应用程序来说,使用这种Manifests来“Override and Redirect”所依赖程序集的版本。
l 发行配置文件(Publisher Configuration Files):用于重定向并行组件的版本倒另外一个合适的版本的Manifests。此时,被重定向的新程序集应该和原来的旧程序集具有相同的主.次(majou.minor)版本号。
5 Windows对于Manifest的处理
XP以前版本的windows,会像以前那样执行这个exe文件,寻找相应的dll,没有分别,Manifest只是个多余的文件或资源,dll文件会直接到system32的目录下查找,并且调用。
而XP及其以后的操作系统,则会首先读取Manifest,获得exe文件需要调用的DLL列表(此时获得的,并不直接是DLL文件的本身的位置,而是DLL的manifest)操作系统再根据DLL的Manifest提供的信息去寻找对应的DLL ,这样就可能区别不同版本的同一个DLL文件。
这就说明了为什么我的程序可以在2000下面运行,而在XP及2003上无法运行。
6 VS2005 种的 Manifest 配置
使用 Visual Studio 2005 以后的一个新问题是, VS2005 带的 8.0 新版的 C 运行库 (VC 8.0 CRT) 文件在 XP 以后支持 manifest 的 Windows 版本中被调用时,将会 check 一下 Application 自身的 Manifest ,否则将会拒绝被调用,这也就是说,使用 Visual Studio 开发的 Application , Manifest 将是必不可少的 (搞不懂 MS 为啥要这样设置,反正与 VS2003.NET 不同了,也许除了 MS 自己说的哪些冠冕堂皇的原因,至少这样一来 Linux 的 Wine 模拟要麻烦多了)
不过,如果你的程序是静态链接的,没有使用 dll ,且只使用了操作系统核心的 Kernel32.dll, User32.dll, Ole32.dll, 或 ShDocVW.dll 等,那么你可以不需要考虑 Manifest , 可以关掉它。此时,在 VS2005 种中, project 的设置必须是 Use Standard Windows Libraries 、 Not Using ATL 、 No Common Language Runtime support