VC manifest

VC manifest

分类: c++ MFC   1121人阅读  评论(0)  收藏  举报

 从VS2005开始,微软在VC的编译选项中添加了manifest这个功能,这将有助于软件以Side-by-Side方式运行。

    采用/MD和/MDd运行时库选项的项目manifest是必要的。当程序启动时发生类似下图找不到MSVCRxxx.dll时可能就是程序没有正确的嵌入清单文件。

VC manifest - 秒大刀 - 秒大刀的城堡

怎样给程序嵌入manifest清单?

    打开默认的manifest链接功能需要修改两处配置:项目属性→配置属性→链接器→清单文件→生成清单,设置为“是”;项目属性→配置属性→清单工具→输入和输出→嵌入清单,设置为“是”。生成解决方案即可。

    若要关闭清单嵌入功能则可将上述选项改为“否”。

找不到MSVCR xxx .dll ?

    确认安装了相应版本的VC运行时库。采用/MD和/MDd编译的VC程序运行时需要有VC运行时库可再发行组件包的支持(下载VC可再发行组件包)。你也可以将对应的运行时库dll和应用程序一起打包发布,当然这无疑会增大厂商的发布负担和客户的存贮负担。

    确认应用程序正确的嵌入或配置了manifest清单文件。

关键的 Error 14001 ?

   用VS自带的错误查找工具得到的解释为:“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”。该错误在P/Invoke下表现为Exception from HRESULT: 0x800736B1 。

   通常该错误意味着应用程序的依赖dll库找不到或者依赖库的依赖库找不到。用Dependency Walker可以方便的查看应用程序依赖的dll是否存在。补上找不到的dll一般就没啥问题了。一些公用的dll可以从http://www.dll-files.com/获取。

    如果发现Dependency Walker的日志窗口出现类似下面的报错,需特别注意:

    Error: The Side-by-Side configuration information for "YOUR.DLL" contains errors.This application has failed to start because the application configuration is incorrect.Reinstalling the application may fix this problem (14001).

    此时应该确认所以被依赖的dll(包括被间接依赖的dll)中内嵌的manifest所依赖的运行时库都是可用的。如果这些dll所依赖的运行时库是不同的,则应该安装这些依赖的运行时库或将对应的dll拷贝到应用程序所在目录。

    可以在VS直接打开exe或者dll文件来导出查看manifest的内容。

VC manifest - 秒大刀 - 秒大刀的城堡

    一些担当库角色的dll可能是由第三方在很早以前就生成好的,应用程序发布时相应的运行时库可能已经很难获得,要针对每个dll都找到其对应的运行时库版本就更难了。将所有这些不同版本的运行时库都搜集齐并安装给最终用户也实在是一种羞辱,微软早已保证了新版本的运行时库向前兼容。

   那,怎么做?怎么做才能让这些早期发布的dll自动绑定到新版本的运行时库?

   将manifest过早的嵌入到dll中本身就是一种错误,这种硬绑定直接限制了dll自动升级到新的运行时库,并会导致其他一系列问题。比如,程序将无法从一个模块中申请内存然后在另外一个模块中释放,即使采用的是/MD选项,也因不同版本的运行时库内存管理不在一个堆上,棘手的跨模块的内存管理问题扑面而来。倒!

    最好的做法是:仅在一个地方(可执行文件)嵌入manifest来指明运行时库,不要在任何dll中采用manifest。

    当然也可以选择非嵌入的manifest,这样后期升级只要手动更改xml文件即可。

 

参考:

《How to: Deploy using XCopy》

《Redistributing Visual C++ Files》




  Windows XP通过XML文件来实现这一功能,这些XML文件保存了有关应用程序配置的元数据,这里所说的XML文件,就是Manifest清单文件。
Manifest事实上就是一个以.manifest为后缀的XML文件,用于组织和描述隔离应用程序及并行组件,其内部的信息如<assemblyIdentity>元素则标识着一个唯一的程序集,和其他信息一起,他们用于COM类、接口及库的绑定和激活,而这些信息,以往都是存储在注册表中的。另外,Manifests也制定了组成程序集的文件及Windows类。

一、Manifest的分类
  在Windows XP中,事实上是在.NET中,把Manifests分类为如下几种类型:
  1、程序集Manifests(Assembly Manifests):主要用于描述程序集,管理程序集的名字、版本、资源、依赖程序集。其中共享程序集的Manifests存储在Windows的WinSxS目录中。私有的程序集Manifests则存可以作为一个资源存储在DLL中,也可以存储在应用程序目录下。
  2、应用程序Manifests(Application Manifests):这类Manifests则用于描述隔离应用程序,它管理着此应用程序在运行时要绑定的共享的并行组件的名字、版本。该Manifests可以作为一个文件(.manifest文件)存储在应用程序相同的目录下,也可以作为一种资源嵌入在可执行文件内部(Embed Manifest)。
  3、应用程序配置文件(Application Configuration Files):对于并行组件及隔离应用程序来说,使用这种Manifests来“Override and Redirect”所依赖程序集的版本。
  4、发行配置文件(Publisher Configuration Files):用于重定向并行组件的版本倒另外一个合适的版本的Manifests。此时,被重定向的新程序集应该和原来的旧程序集具有相同的主.次(majou.minor)版本号。

二、Windows对于Manifest的处理
  XP以前版本的windows,会像以前那样执行这个exe文件,寻找相应的dll,没有分别,Manifest只是个多余的文件或资源,dll文件会直接到system32的目录下查找,并且调用。
  而XP及其以后的操作系统,则会首先读取Manifest,获得exe文件需要调用的DLL列表(此时获得的,并不直接是DLL文件的本身的位置,而是DLL的manifest)操作系统再根据DLL的Manifest提供的信息去寻找对应的DLL ,这样就可能区别不同版本的同一个DLL文件。
  这就说明了为什么我的程序可以在2000下面运行,而在XP及2003上无法运行。这也使得很多木马可以利用这个特点实现限制安全软件。

三、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。

开心

分类:  windows编程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值