一、原理
XP以上的操作系统支持COM免注册技术,操作系统在加载EXE时会自动扫描是否包含配套的manifest信息,若有则读取manifest内容加载组件,否则读取注册表。
manifest描述了EXE里面引用了哪个DLL库、DLL里面提供了什么接口等信息,只要给EXE、DLL加上配套manifest即可完成免注册工作。
二、Manifest清单文件
Windows XP开始,系统通过XML文件来实现这一功能,这些XML文件保存了有关应用程序配置的元数据,这里所说的XML文件,就是Manifest清单文件。
Manifest事实上就是一个以.manifest为后缀的XML文件,用于组织和描述隔离应用程序及并行组件,其内部的信息如<assemblyIdentity>元素则标识着一个唯一的程序集,和其他信息一起,他们用于COM类、接口及库的绑定和激活,而这些信息,以往都是存储在注册表中的。另外,Manifests也制定了组成程序集的文件及Windows类。
与执行Name.exe配套的Manifest文件的文件名,Name.exe.Manifest。
三、Manifest清单机制
这是Windows的Assembly Manifest机制,其功能就是为了解决以前windows上的“Dll hend”(“Dll 地狱”)问题,建立的一种DLL管理解决方案。
Dll是动态加载共享库,同一个Dll可能被多个程序所使用,而所谓“Dll 地狱”就是当不通程序依赖的Dll相同,但版本不同时,由于系统不能分辨到底哪个是哪个,所以加载错了Dll版本,然后就挂了。windows对EXE文件,配套一个程序集清单的文件。让每个程序都有一个清单,列出其所需要的所有依赖,这儿所列出的依赖可不是简单地靠文件明来区分的,而是根据一种叫做“强文件名”的东西区分的,那么什么是强文件明呢?我们来看一下这个.manifest文件便知道了
四、manifest结构
1、在Windows中,manifest(清单)是一个XML文件,根据清单类型不同,可以分为以下几种:
mainfest 功能 | |
Manifest | 描述 |
程序集清单 | 描述名称、版本、资源、依赖的side-by-side程序集 |
应用程序清单 | 描述共享的side-by-side的程序集版本和名称,可能包含私有side-by-side的程序集元数据 |
应用程序配置文件 | 重定向每一个应用程序依赖的程序集版本 |
发布者配置文件 | 使用发布者配置重定向一整块的程序集版本 |
2、Manifest文件XML内部结构
MXL结构 | |||
元素 | 属性 | 是否必须 | 说明 |
assembly | yes | xml的根节点 | |
manifestVersion | 固定为:1.0 | ||
noInheritable | No | 多线程不继承清单,如果没有则默认继承。会被应用清单覆盖 | |
assemblyIdentity | Yes | 程序集唯一标识 | |
type | Yes | 该值必须是win32 | |
name | Yes | 程序集的唯一名称 | |
language | No | 标识程序集的语言 | |
processorArchitecture | No | 处理器架构,x86或ia64 | |
version | Yes | 指定程序集版本,格式如:mmmmm.nnnnn.ooooo.ppppp,数值范围0-65535(含) | |
publicKeyToken | No | 16个字符的十六进制字符串,表示对程序集签名的公共密钥sha-1哈希的最后8个字节,对于共享的并行程序集是必须的 | |
dependency | No | 包含至少一个dependentAssembly子元素 | |
dependentAssembly | No | 第一个子元素必须为assemblyIdentity,描述该程序集依赖哪些程序集 | |
file | No | 该程序集使用的文件 | |
name | Yes | 文件名称,例如,Conctl32.dll | |
hashalg | No | 文件的hash算法,该值为SHA1 | |
hash | No | 文件的hash值 | |
comClass | No | COM组件 | |
description | No | class名称 | |
clsid | Yes | 唯一标识类的GUID | |
threadingModel | No | 进程内COM类使用的线程模型 | |
tlbid | No | 此COM组件的GUID | |
progid | No | 此COM组件的ProgID | |
miscStatus | No | 和COM组件有关,具体可以参考OLEMISC枚举 | |
miscStatusIcon | No | 和COM组件有关,具体可以参考OLEMISC枚举 | |
miscStatusContent | No | 和COM组件有关,具体可以参考OLEMISC枚举 | |
miscStatusDocPrint | No | 和COM组件有关,具体可以参考OLEMISC枚举 | |
miscStatusThumbnail | No | 和COM组件有关,具体可以参考OLEMISC枚举 | |
typelib | No | 类型库 | |
tlbid | Yes | 类型库的唯一ID | |
version | Yes | 版本 | |
helpdir | Yes | 帮助目录 | |
resourceid | No | 资源ID | |
flags | No | 标志 | |
comInterfaceExternalProxyStub | No | com接口扩展代理存根 | |
iid | Yes | 代理接口的IID | |
baseInterface | No | 基类的IID | |
numMethods | No | 接口实现的方法数 | |
name | No | 接口名称 | |
tlbid | No | 类型库 | |
proxyStubClsid32 | No | 将IID映射到32位代理DLL中的CLISID | |
comInterfaceProxyStub | No | com接口代理存根 | |
iid | Yes | 代理接口的IID | |
name | Yes | 接口名称 | |
tlbid | No | 类型库 | |
baseInterface | No | 基类接口IID | |
numMethods | No | 接口实现的方法数 | |
proxyStubClsid32 | No | 代理存根32位CLISID | |
threadingModel | No | 进程内COM使用的线程模型 | |
windowClass | No | 版本化的Windows类 | |
versioned | No | 版本,默认yes |
四、Manifest使用方式
1、嵌入EXE,通过将资源文件嵌入EXE文件中。
2、在执行文件,同一目录中建立同名的清单文件。
程序(执行)文件:MyName.exe,清单文件MyName.exe.manifest
或Dll文件,MyName.dll,清单文件MyName.dll.manifest
五、Manifest实现
使用通行的编译程序,如C、C++、Delphi等,编译项目组(创建EXE执行文件)时:
- 创建Mainfest文件
- 编译生成EXE文件相同目录中
- 编译EXE文件
其它:
- 锐浪报表 Grid++Report 免注册DLL C/S报表开发(一)
- 锐浪报表 Grid++Report 免注册DLL C/S报表开发(二)清单文件manifest分析
更多推荐
Windows COM 免注册 manifest 清单文件
发布评论