Side by Side Assembly介绍--manifest文件的使用

什么是Side-by-Side Assembly?

Side-by-Side Assembly(建称SxS)是微软在Visual Studio 2005(Windows 2000?)中引入的技术,用来解决Windows平台上的DLL Hell问题。DLL Hell的介绍可以看Wikipedia的文章。简单的说,DLL Hell窘境包括了Windows应用程序依赖的DLL带来的若干问题,包括同名DLL、DLL升级、DLL载入顺序等等。

Side-by-Side Assembly按照我的理解,是一种特殊的DLL,按照Side-by-Side Assembly的要求开发的,并用XML格式的manifest和policy文件描述的。所有的系统Side-by-Side Assembly都安装在Windows目录下的WinSxS子目录里,有一堆的目录、DLL和XML文件。

Side-by-Side Assembly的使用参见MSDN。但MSDN有把简单问题复杂化的毛病,原理讲的很多,实际例子举的很少,不看也罢。

使用Side-by-Side Assembly包括两个方面,一方面是自己开发的应用程序和DLL如何依赖Side-by-Side Assembly,另一方面是如何开发自己的Side-by-Side Assembly。如果只关心第一个方面,问题要简单的多。不需要关心第二个方面的原因如下。

Visual Studio 2010要取消对Side-by-Side Assembly的默认支持?

消息来源于微软的博客,根据文章介绍,2010要改变对应用默认采用的SxS发布方式,回到类似2003的方式,同时支持对CRT的静态和动态联编,对DLL的搜索顺序也是常用的:先搜索应用程序目录,然后System32,然后PATH。

当然SxS还是有的,应该只是Visual Studio不再在开发应用时默认采用。

应用如何依赖Side-by-Side Assembly

cl.exe在链接生成EXE的时候,会同时生成一个同名的manifest文件。该文件是XML格式的,描述了EXE对SxS的依赖。下面是一个manifest的例子:

<?xmlversion="2.0"encoding="UTF-8"standalone="yes"?>
<assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestversion="1.0">
<trustinfoxmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedprivileges>
<requestedexecutionleveluiaccess="false"level="asInvoker"></requestedexecutionlevel>
</requestedprivileges>
</security>
</trustinfo>
<dependency>
<dependentassembly>
<assemblyidentityname="Microsoft.VC90.CRT"publickeytoken="1fc8b3b9a1e18e3b"processorarchitecture="x86"version="9.0.21022.8"type="win32"></assemblyidentity>
</dependentassembly>
</dependency>
</assembly>

如果删除这个manifest文件,运行该EXE会出现类似下面的错误:

这是因为缺少manifest文件的描述,程序不知道如何载入WinSxS目录下的DLL。所以最好把manifest文件嵌入EXE中,可以用mt.exe工具完成这一工作:

mt.exe -manifest <manifest-file> -outputresource:<exe-file>;#1

用IDE开发不存在这个问题,IDE会自动调用mt.exe将manifest嵌入EXE

DLL如何依赖Side-by-Side Assembly

同上述原因,DLL生成之后,最好也用mt.exe将manifest文件嵌入。方法与上面类似,不同之处在资源ID应该是2而不是1,其中的区别参见【1】【2】,硬记也行,没什么道理。

mt.exe -manifest <manifest-file> -outputresource:<dll-file>;#2

用IDE开发也不存在这个问题,IDE会自动调用mt.exe将manifest嵌入DLL

如何绕过Side-by-Side Assembly?

Side-by-Side Assembly带来了很多不便,比如说,依赖SxS MSVCR90.dll的程序在没有安装VC redistributable的系统中不能运行,像是WinPE环境。因此最好有一种绕过SxS的方法,将SxS的Assembly和EXE放在一个目录下,避免依赖系统WinSxS目录下的Assembly。

1. 首先,我们需要manifest文件,如果手头没有EXE和DLL的manifest文件,可以用mt.exe工具从EXE和DLL中导出manifest文件

导出EXE的manifest

mt.exe -inputresource:<exe-file>;#1 -out:<manifest-file>

导出DLL的manifest

mt.exe -outputresource:<dll-file>;#2 -out:<manifest-file>

2. 根据manifest中的信息,创建若干新的manifest文件。新manifest文件名和EXE中依赖的Assembly名字对应,例如按照前面的manifest例子,应该对应创建一个Microsoft.VC90.CRT.manifest,内容格式如下:

<?xmlversion="2.0"encoding="UTF-8"standalone="yes"?>
<assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestversion="1.0">
<noinheritable></noinheritable>
<assemblyidentityname="Microsoft.VC90.CRT"publickeytoken="1fc8b3b9a1e18e3b"processorarchitecture="x86"version="9.0.21022.8"type="win32"></assemblyidentity>
<filename="msvcr90.dll"></file>
<filename="msvcp90.dll"></file>
</assembly>

其中assemblyIdentity和原EXE的内容要完全一样。

3. 根据manifest文件中的assemblyIdentity信息,到系统的WinSxS目录下的子目录里找DLL,子目录名的格式是<processorArchchitecture>-<name>-<publicKeyToken>-<version>-none-xxx。把子目录下的DLL拷贝到EXE所在的目录下。把DLL的名字写入新manifest的file标签下。

至此,已经把Assembly放到EXE所在目录下,EXE也不再依赖系统WinSxS目录下的Assembly了。

VC 2005和VC 2008相关的SxS打包

我把自己系统中WinSxS目录下所有x86_micosoft.vc开头的目录全部拷贝出来,打了个包,以备不时之需。(下载链接

时间: 2024-08-19 12:12:37

Side by Side Assembly介绍--manifest文件的使用的相关文章

什么是 .manifest 文件

恩,为了大家都能很方便的理解,我将尽量简单通俗地进行描述. [现象]对这个问题的研究是起源于这么一个现象:当你用VC++2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把此exe文件拷贝到别人电脑上时,便不能运行了,大致的错误提示如下:应用程序配置不正确,请重新安装程序--或者是MSVCR80D.dll 没有找到什么的(我记得不是很清楚,不过大致是这样的) [分析]看到这样的提示,当然不会傻到重装咯.第一反应应该是什么配置有问题.或者是缺少了什么依赖的库文件:于是我

Android应用程序的组成部分和Manifest文件(转)

Android应用程序由松散耦合的组件组成,并使用应用程序Manifest绑定到一起:应用程序Manifest描述了每一组件和它们之间的交互方式,还用于指定应用程序元数据.其硬件和平台要求.外部库以及必需的权限. 一.应用程序的基本结构模块 · Activity:应用程序的表示层.每个UI都是通过Activity类的一个或多个扩展实现的.Activity使用Fragment和视图来布局和显示信息,以及响应用户动作. · Service:应用程序中不可见的工作者.运行时没有UI,可以更新数据源和A

Android应用程序组成部分 Manifest文件 Manifest文件节点

Android应用程序的组成部分和Manifest文件 Android应用程序由松散耦合的组件组成,并使用应用程序Manifest绑定到一起:应用程序Manifest描述了每一组件和它们之间的交互方式,还用于指定应用程序元数据.其硬件和平台要求.外部库以及必需的权限. 一.应用程序的基本结构模块 · Activity:应用程序的表示层.每个UI都是通过Activity类的一个或多个扩展实现的.Activity使用Fragment和视图来布局和显示信息,以及响应用户动作. · Service:应用

Android的Manifest文件详解

Manifest可以定义应用程序及其组件和需求的结构和元数组. Android的文档: http://developer.android.com/guide/topics/manifest/manifest-element.html Hello_World, AndroidManifest.xml : <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http:

用MT.exe将exe中的manifest文件提取出来和将manifest文件放入exe中

 前一种方法是将manifest文件放入exe中,但是要记得需要在工程中设置 这样的话exe中就不存在manifest了,在debug目录下就会看到相应的manifest文件.后者是将exe中的manifest文件提取出来,但是exe中依然有manifest文件!  

介绍Inf文件更多的应用

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;   INF文件全称Information File文件,是Winodws操作系统下用来描述设备或文件等数据信息的文件.INF文件是由标准的ASCII码组成,您可以用任何一款文字编辑器查看修改其中的内容. 一般我们总是认为INF文件是系统设备的驱动程序,其实这是错误的认识,Windows之所以在安装某些硬件的驱动时提示需要INF文件是因为INF文件为该设备提供了一个全

Android Manifest.xml文件解析

一.关于AndroidManifest.xml AndroidManifest.xml是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置.除了能声明程序中的Activities, ContentProviders, Services, 和Intent Receivers,还能指定permissions和instrumentation(安全控制和测试) 二

Android中的manifest清单文件简介

写过java程序的人,都知道了配置文件时java实现各种各样的框架的一大利器,manifest清单文件对 android的作用自然不言而喻,然而他里面究竟定义了些什么,并且他是如何加载到程序中的. 他里面定义了什么了,定义的无非是一些android程序配置的节点信息.我们打开他的开发文档,能够精确 的看到清单文件的定义. android中manifest文件的定义为. <?xmlversion="1.0"encoding="utf-8"?> <ma

又议android中的manifest清单文件

写过java程序的人,都知道了配置文件时java实现各种各样的框架的一大利器,manifest清单文件对android的作用自然不言而喻,然而他里面究竟定义了些什么,并且他是如何加载到程序中的. 他里面定义了什么了,定义的无非是一些android程序配置的节点信息.我们打开他的开发文档,能够精确的看到清单文件的定义. android中manifest文件的定义为. <?xmlversion="1.0"encoding="utf-8"?> <mani