AssemblyManifest通俗简易手册.doc_第1页
AssemblyManifest通俗简易手册.doc_第2页
AssemblyManifest通俗简易手册.doc_第3页
AssemblyManifest通俗简易手册.doc_第4页
AssemblyManifest通俗简易手册.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Assembly Manifest 通俗简易手册恩,为了大家都能很方便的理解,我将尽量简单通俗地进行描述。现象对这个问题的研究是起源于这么一个现象:当你用VC+2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把此exe文件 拷贝到别人电脑上时,便不能运行了,大致的错误提示如下:应用程序配置不正确,请重新安装程序或者是MSVCR80D.dll 没有找到什么的(我记得不是很清楚,不过大致是这样的)分析看到这样的提示,当然不会傻到重装咯。第一反应应该是什么配置有问题、或者是缺少了什么依赖的库文件;于是我就根据以前Windows缺少库文件的经验, 把所有库文件(.DLL)统统一股脑地复制到当前文件夹下来,满心欢喜以为可以运行了,以运行#¥#¥还是挂了。探索于是开始网上搜索,我Google,我摆渡;渐渐我发现,这一切都和一个叫做*.manifest 类型的文件发生关系,那么到底什么是 .manifest 文件呢?他有什么用,以前为什么没有?后来,经过艰苦努力,终于得知,原来这一切都是Windows 的Assembly Manifest搞的鬼。这个东东的作用就是为了解决 以前windows上的“Dll 地狱” 问题才产生的新的DLL管理解决方案。大家知道,Dll是动态加载共享库,同一个Dll可能被多个程序所使用,而所谓“Dll 地狱”就是当不通程序依赖的Dll相同,但版本不同时,由于系统不能分辨到底哪个是哪个,所以加载错了Dll版本,然后就挂了。于是盖茨就吸取了教训,搞 了一个程序集清单的东东,每个程序都要有一个清单,这个清单存再和自己应用程序同名的.manifest文件中,里面列出其所需要的所有依赖,这儿所列出 的依赖可不是简单地靠文件明来区分的,而是根据一种叫做“强文件名”的东西区分的,那么什么是强文件明呢?我们来看一下这个.manifest文件便知道 了。我们发现原来这是一个XML格式的文件,其中这一部分指明了其依赖于一个名字叫做Microsoft.VC80.CRT的库。但是我们发现,属性里面还有其它的东东,分别是type系统类型,version版本号,processorArchitecture平台环境,publicKeyToken公匙(一般用来标示一个公 司)把他们加在一起便成了“强文件名”了,有了这种“强文件名”,我们就可以根据其区分不同的版本、不同的平台总之,有了这种强文件名,系统中可 以有多个不同版本的相同的库共存而不会发生冲突。深入恩,那么现在,我们就来具体了解一下这一套机制。首先是强弱文件名的问题。正如上面提到的那样,为了区分不同版本或不同厂商生成的相同的程序集,必须用一个Assembly Manifest程序清单来列出我这个程序集的强文件名慢着,到这里你可能会问:刚才不是说Assembly Manifest程序清单是列出其所依赖的程序集的强文件名呢,怎么这里变成了当前文件的强文件明了呢?其实,Assembly Manifest程序清单有两部分功能,上面这个实例之所以标注了其所依赖的文件的强文件名是因为其是客户端的Assembly Manifest,在服务端有另外一个Manifest 来标注。phRUExlAeZ8BwmlD8VlO5udAnRE=7AY1JqoUvK3u/6bYWbOagGgAFbc=hWq8zazTsMeKVxWFBa6bnv4hEOw=这个便是从WINDOWSWinSxSManifests目录下取出来的一个manifest文件,再这个文件夹下有一陀子这种XML格式的 manifest文件,其是服务端的程序清单。WinSxs是windows XP以上版本提供的blue非托管并行缓存(side-by-side catche)/blue里面安装了各种版本的经过强文件名签名的系统库,而上面这个文件正是标注 了系统中Microsoft.VC80.CRT的一个版本的强文件名签名,如果其和客户端。.manifest 清单里面所列出的依赖项对上的话,就会被加载。刚才说的side-by-side 是指各种不同的版本并行运行。上面这个服务端manifest文件中标签具体指明了当前强文件名签名的到底是哪一个文件,其中还有这个文件的Hash签名,以确保文件的完整性。好了,有了这一套机制,就可以非常非常安全地进行库文件关联了,但是、但是貌似还有一个一直困扰我们的问题:这套机制安全是安全了,但是却失去了以前良好 的前后版本兼容性,即如果你的系统库发生了升级,那么服务端的版本号发生了变化,那岂不是所有服务端程序都不能使用了吗?其实,windows还使用一个 policy的策略文件来确认映射关系。这便是在WINDOWSWinSxSPolicies目录下的一个Policy文件,其中标签便指定 了所有8.0.41204.256-8.0.50608.0变本的客户需求映射到8.0.50727.42这个我现在系统中安装的比较新的版本的库。当然 我们也能对别的字段进行映射,这样便能很好解决系统升级带来的问题。应用经过以上的讲解,大家对整个依赖查找过程都有了一个整体的认识,那么在实际中问题就好解决了。让我们回到实际问题中,我之前说了,把一个程序编译连接成可执行程序后,在别人的电脑上发现找不到其所依赖的库了,那么怎么办呢?聪明的你自然想到把其所 依赖的库相应的版本拷贝到目标计算机上面,可是当你在拼命寻找那个可执行文件的assembly manifests文件的时候,却突然发现找不到了,在执行目录下面明明只有一个exe文件嘛。是不是没有生成呢?显然不会,原来是资源连接器把那个 assembly manifests文件连接到了可执行文件里面了;不信,你可以用你的vc+打开一个可执行文件看看,在其资源项里面就有一个叫做 RT_MANIFEST的项目。这个里面就是二进制标示的manifests文件。那么根据这里面提供的要求,将相应版本的依赖文件(一般就是CRT运行 库)拷贝到系统目录WindowsWinSxS,记住一般会是连带着一个特殊命名的目录一起拷贝到那个文件夹下,比如CRT的运行库就是WinSxS x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50608.0_x-ww_b7acac55有这样一个目录,其标注了此库的版本号以及签名等信息,以防止多个版本重名时不能复制到同一WinSxS目录下。这样就搞定了么?如果是以前,那么一切都解决了,系统会在这个目录下面找到这个运行库,可是现在单单这样可不行,系统可是要找到这个运行库的 assembly manifests文件,并且对比强文件名之后才能加载,所以所以千万别忘了把相应的manifests文件拷贝到WinSxSManifests目 录下面。当然,这样在目标的系统文件夹下面打动干戈,自然有些过于暴动了,还好,Windows还为我们提供了一种私有查找方式。这种方式会在前面的位置找不到合 适库的时候在本地文件夹下面找。所以你只要把之前的库以及那个manifests文件一起拷贝到你的应用程序的路径下面,就可以使用啦。根据MSDN的说明,在本地查找并加载遵循一下规则:在应用程序本地文件夹中查找名为 .manifest 的清单文件。在此示例中,加载程序试图在 appl.exe 所在的文件夹中查找 Microsoft.VC80.CRT.manifest。如果找到该清单,加载程序将从应用程序文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。尝试在 appl.exe 本地文件夹中打开文件夹 ,如果存在此文件夹,则从中加载清单文件 .manifest。如果找到该清单,加载程序将从 文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。最后,我想补充的一点是,在你的VC+安装目录下面的“Microsoft Visual Studio 8VCredist”目录下,有着所有的提供发布的已经配备相应.manifest的库文件。所以你想要发布一个程序最简单最安全

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论