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开头的目录全部拷贝出来,打了个包,以备不时之需。(下载链接)
Side by Side Assembly介绍--manifest文件的使用的更多相关文章
- Android manifest文件中的标签详细介绍
官方文档 概要 每一个Android应用都应该包含一个manifest文件,即AndroidManifest.xml.它包含了程序运行的一些必备信息,比如:--为Java应用程序指定一个独一无二的名字 ...
- 利用manifest文件对程序目录下的dll进行分类
1 背景 对于大部分的券商和机构投资者,只能通过有交易所交易系统接入资质的券商提供的柜台系统来进行现货交易.相对于期货市场,现货市场的柜台系统千差万别,接入协议有明文字符串.二进制数据和FIX协议等, ...
- 什么是 .manifest 文件
恩,为了大家都能很方便的理解,我将尽量简单通俗地进行描述. [现象]对这个问题的研究是起源于这么一个现象:当你用VC++2005(或者其它.NET)写程序后,在自己的计算机上能毫无问题地运行,但是当把 ...
- Android学习笔记(二)Manifest文件节点详解
在上一篇博文中简单介绍了Manifest文件及其存放位置,本篇就来详细介绍一下Manifest文件中的节点和一些节点的基本作用,首先看一下Manifest文件最基本的结构: <manifest ...
- Android应用程序的组成部分和Manifest文件(转)
Android应用程序由松散耦合的组件组成,并使用应用程序Manifest绑定到一起:应用程序Manifest描述了每一组件和它们之间的交互方式,还用于指定应用程序元数据.其硬件和平台要求.外部库以及 ...
- 在Vista操作系统中通过manifest文件使VC应用程序获得管理员权限
原文 VC编译出来的应用程序在vista下运行,有可能因为权限问题,不能成功运行. 用以下办法,给应用程序添加一个manifest文件,程序运行时系统就会跳出UAC对话框,获得管理权限. 1.打开应用 ...
- Android 在 manifest 文件里增加 versionCode,运行后版本并没有随之增加
现象:从 git 上拉下来的代码中 versionCode 是8,versionName 是1.0.7但运行后的版本仍然是1.0.6 原因:全文搜索1.0.6之后发现在 bin 目录下也有一个 man ...
- HTML5 的 applicationCache 应用程序缓存离线存储功能与 manifest 文件
一. 实现 HTML5 applicationCache 的步骤 一般的操作步骤 1. 新建 manifest 文件 如文件名为 lzwme.manifest,内容配置参考如下: 01 CACHE ...
- LevelDB源码之五Current文件\Manifest文件\版本信息
版本信息有什么用?先来简要说明三个类的具体用途: Version:代表了某一时刻的数据库版本信息,版本信息的主要内容是当前各个Level的SSTable数据文件列表. VersionSet:维护了一份 ...
随机推荐
- Android 源码编译及常见错误及解决方法
最近要往arm开发板上移植android系统,大大小小的问题遇到了太多太多,都是泪啊.本人初接触嵌入式开发,对问题的根源不是太了解,不过好在每解决一个问题,便记录一下.话不多说,正式罗列问题: hos ...
- 利用HibernateTools从数据库表生成带注解的POJO
在SSH框架中,如果先设计好了数据库,那么下一步就需要从数据库Table生成实体java类和hbm.xml配置文件.在最新的开发框架中,已经支持使用注解,从而避免了繁琐的hbm.xml配置,而且我们可 ...
- Google的小秘密
google有计算器的功能,例如在google中搜索25*25.lg(13)等,看会出现什么样的结果. http://www.google.com/microsoft 微软风格的入口 http: ...
- C#让TopMost窗体弹出并置顶层但不获取当前输入焦点的终极办法
为了使程序在弹出窗口时置顶层且不获取系统输入焦点,避免影响用户当前的操作,来电通来电弹屏软件尝试过N多种办法,例如:弹出前保存当前焦点窗口句柄,弹出时因为使用TopMost系统默认将焦点交给了弹出窗口 ...
- 設定 Bootstrap/SASS/Bower/gulp (Windows平台)
請注意:在進行以下步驟前,你會需要先安裝git,可以參考這篇 git安裝教學 前言 時至今日,幾乎每個人都在討論bootstrap.less 或 sass.我們知道它們是比較新的前端技術,而且有開始愈 ...
- cxgrid HyperLink 鼠标显示效果
procedure TForm1.cxGrid1DBTableView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); v ...
- Kakfa揭秘 Day5 SocketServer下的NIO
Kakfa揭秘 Day5 SocketServer下的NIO 整个Kafka底层都是基于NIO来进行开发的,这种消息机制可以达到弱耦合的效果,同时在磁盘有很多数据时,会非常的高效,在gc方面有非常大的 ...
- PythonCrawl自学日志(3)
2016年9月21日09:21:431.爬虫的抓取周期:(1)首先生成初始请求爬第一个url,并指定一个回调函数被称为与下载这些请求的响应.(2)第一个请求执行通过调用 start_requests( ...
- C++中delete和delete[]的区别
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]. 关于 new[] 和 delete[],其中又 ...
- android studio 打开github开源代码
1.最近下载的开源代码全是github来的,一直用eclipse开发,对于android studio来说是全新的 2.在eclipse导入一个工程那是so easy, import选择一下就可以. ...